/src/srun/libsrun/opt.c
C | 2668 lines | 2263 code | 212 blank | 193 comment | 428 complexity | 0aea047511aa93a759b9be877dfd2ded MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /*****************************************************************************\
- * opt.c - options processing for srun
- *****************************************************************************
- * Copyright (C) 2002-2007 The Regents of the University of California.
- * Copyright (C) 2008-2010 Lawrence Livermore National Security.
- * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- * Written by Mark Grondona <grondona1@llnl.gov>, et. al.
- * CODE-OCEC-09-009. All rights reserved.
- *
- * This file is part of SLURM, a resource management program.
- * For details, see <http://www.schedmd.com/slurmdocs/>.
- * Please also read the included file: DISCLAIMER.
- *
- * SLURM is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * In addition, as a special exception, the copyright holders give permission
- * to link the code of portions of this program with the OpenSSL library under
- * certain conditions as described in each individual source file, and
- * distribute linked combinations including the two. You must obey the GNU
- * General Public License in all respects for all of the code used other than
- * OpenSSL. If you modify file(s) with this exception, you may extend this
- * exception to your version of the file(s), but you are not obligated to do
- * so. If you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files in
- * the program, then also delete it here.
- *
- * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with SLURM; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- \*****************************************************************************/
- #if HAVE_CONFIG_H
- # include "config.h"
- #endif
- #include <string.h> /* strcpy, strncasecmp */
- #ifdef HAVE_STRINGS_H
- # include <strings.h>
- #endif
- #ifndef _GNU_SOURCE
- # define _GNU_SOURCE
- #endif
- #if HAVE_GETOPT_H
- # include <getopt.h>
- #else
- # include "src/common/getopt.h"
- #endif
- #ifdef HAVE_LIMITS_H
- # include <limits.h>
- #endif
- #include <fcntl.h>
- #include <stdarg.h> /* va_start */
- #include <stdio.h>
- #include <stdlib.h> /* getenv */
- #include <sys/param.h> /* MAXPATHLEN */
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/utsname.h>
- #include "src/common/cpu_frequency.h"
- #include "src/common/list.h"
- #include "src/common/log.h"
- #include "src/common/mpi.h"
- #include "src/common/optz.h"
- #include "src/common/parse_time.h"
- #include "src/common/plugstack.h"
- #include "src/common/proc_args.h"
- #include "src/common/slurm_protocol_api.h"
- #include "src/common/slurm_protocol_interface.h"
- #include "src/common/slurm_rlimits_info.h"
- #include "src/common/slurm_resource_info.h"
- #include "src/common/uid.h"
- #include "src/common/xmalloc.h"
- #include "src/common/xstring.h"
- #include "src/api/pmi_server.h"
- #include "debugger.h"
- #include "launch.h"
- #include "multi_prog.h"
- #include "opt.h"
- /* generic OPT_ definitions -- mainly for use with env vars */
- #define OPT_NONE 0x00
- #define OPT_INT 0x01
- #define OPT_STRING 0x02
- #define OPT_IMMEDIATE 0x03
- #define OPT_DISTRIB 0x04
- #define OPT_NODES 0x05
- #define OPT_OVERCOMMIT 0x06
- #define OPT_CONN_TYPE 0x08
- #define OPT_RESV_PORTS 0x09
- #define OPT_NO_ROTATE 0x0a
- #define OPT_GEOMETRY 0x0b
- #define OPT_MPI 0x0c
- #define OPT_CPU_BIND 0x0d
- #define OPT_MEM_BIND 0x0e
- #define OPT_MULTI 0x0f
- #define OPT_NSOCKETS 0x10
- #define OPT_NCORES 0x11
- #define OPT_NTHREADS 0x12
- #define OPT_EXCLUSIVE 0x13
- #define OPT_OPEN_MODE 0x14
- #define OPT_ACCTG_FREQ 0x15
- #define OPT_WCKEY 0x16
- #define OPT_SIGNAL 0x17
- #define OPT_TIME_VAL 0x18
- #define OPT_CPU_FREQ 0x19
- /* generic getopt_long flags, integers and *not* valid characters */
- #define LONG_OPT_HELP 0x100
- #define LONG_OPT_USAGE 0x101
- #define LONG_OPT_XTO 0x102
- #define LONG_OPT_LAUNCH 0x103
- #define LONG_OPT_TIMEO 0x104
- #define LONG_OPT_JOBID 0x105
- #define LONG_OPT_TMP 0x106
- #define LONG_OPT_MEM 0x107
- #define LONG_OPT_MINCPUS 0x108
- #define LONG_OPT_CONT 0x109
- #define LONG_OPT_UID 0x10a
- #define LONG_OPT_GID 0x10b
- #define LONG_OPT_MPI 0x10c
- #define LONG_OPT_RESV_PORTS 0x10d
- #define LONG_OPT_DEBUG_TS 0x110
- #define LONG_OPT_CONNTYPE 0x111
- #define LONG_OPT_TEST_ONLY 0x113
- #define LONG_OPT_NETWORK 0x114
- #define LONG_OPT_EXCLUSIVE 0x115
- #define LONG_OPT_PROPAGATE 0x116
- #define LONG_OPT_PROLOG 0x117
- #define LONG_OPT_EPILOG 0x118
- #define LONG_OPT_BEGIN 0x119
- #define LONG_OPT_MAIL_TYPE 0x11a
- #define LONG_OPT_MAIL_USER 0x11b
- #define LONG_OPT_TASK_PROLOG 0x11c
- #define LONG_OPT_TASK_EPILOG 0x11d
- #define LONG_OPT_NICE 0x11e
- #define LONG_OPT_CPU_BIND 0x11f
- #define LONG_OPT_MEM_BIND 0x120
- #define LONG_OPT_MULTI 0x122
- #define LONG_OPT_COMMENT 0x124
- #define LONG_OPT_QOS 0x127
- #define LONG_OPT_SOCKETSPERNODE 0x130
- #define LONG_OPT_CORESPERSOCKET 0x131
- #define LONG_OPT_THREADSPERCORE 0x132
- #define LONG_OPT_MINSOCKETS 0x133
- #define LONG_OPT_MINCORES 0x134
- #define LONG_OPT_MINTHREADS 0x135
- #define LONG_OPT_NTASKSPERNODE 0x136
- #define LONG_OPT_NTASKSPERSOCKET 0x137
- #define LONG_OPT_NTASKSPERCORE 0x138
- #define LONG_OPT_MEM_PER_CPU 0x13a
- #define LONG_OPT_HINT 0x13b
- #define LONG_OPT_BLRTS_IMAGE 0x140
- #define LONG_OPT_LINUX_IMAGE 0x141
- #define LONG_OPT_MLOADER_IMAGE 0x142
- #define LONG_OPT_RAMDISK_IMAGE 0x143
- #define LONG_OPT_REBOOT 0x144
- #define LONG_OPT_GET_USER_ENV 0x145
- #define LONG_OPT_PTY 0x146
- #define LONG_OPT_CHECKPOINT 0x147
- #define LONG_OPT_CHECKPOINT_DIR 0x148
- #define LONG_OPT_OPEN_MODE 0x149
- #define LONG_OPT_ACCTG_FREQ 0x14a
- #define LONG_OPT_WCKEY 0x14b
- #define LONG_OPT_RESERVATION 0x14c
- #define LONG_OPT_RESTART_DIR 0x14d
- #define LONG_OPT_SIGNAL 0x14e
- #define LONG_OPT_DEBUG_SLURMD 0x14f
- #define LONG_OPT_TIME_MIN 0x150
- #define LONG_OPT_GRES 0x151
- #define LONG_OPT_ALPS 0x152
- #define LONG_OPT_REQ_SWITCH 0x153
- #define LONG_OPT_LAUNCHER_OPTS 0x154
- #define LONG_OPT_CPU_FREQ 0x155
- #define LONG_OPT_LAUNCH_CMD 0x156
- extern char **environ;
- /*---- global variables, defined in opt.h ----*/
- int _verbose;
- opt_t opt;
- int error_exit = 1;
- int immediate_exit = 1;
- char *mpi_type = NULL;
- /*---- forward declarations of static functions ----*/
- static bool mpi_initialized = false;
- typedef struct env_vars env_vars_t;
- /* Get a decimal integer from arg */
- static int _get_int(const char *arg, const char *what, bool positive);
- static void _help(void);
- /* fill in default options */
- static void _opt_default(void);
- /* set options based upon env vars */
- static void _opt_env(void);
- static void _opt_args(int argc, char **argv);
- /* list known options and their settings */
- static void _opt_list(void);
- /* verify options sanity */
- static bool _opt_verify(void);
- static void _process_env_var(env_vars_t *e, const char *val);
- static bool _under_parallel_debugger(void);
- static void _usage(void);
- static bool _valid_node_list(char **node_list_pptr);
- /*---[ end forward declarations of static functions ]---------------------*/
- int initialize_and_process_args(int argc, char *argv[])
- {
- /* initialize option defaults */
- _opt_default();
- /* initialize options with env vars */
- _opt_env();
- /* initialize options with argv */
- _opt_args(argc, argv);
- if (!_opt_verify())
- exit(error_exit);
- if (_verbose > 3)
- _opt_list();
- if (opt.launch_cmd) {
- char *launch_type = slurm_get_launch_type();
- if (!strcmp(launch_type, "launch/slurm")) {
- error("--launch-cmd option is invalid with %s",
- launch_type);
- xfree(launch_type);
- exit(1);
- }
- xfree(launch_type);
- launch_g_create_job_step(NULL, 0, NULL, NULL);
- exit(0);
- }
- return 1;
- }
- /*
- * If the node list supplied is a file name, translate that into
- * a list of nodes, we orphan the data pointed to
- * RET true if the node list is a valid one
- */
- static bool _valid_node_list(char **node_list_pptr)
- {
- int count = NO_VAL;
- /* If we are using Arbitrary and we specified the number of
- procs to use then we need exactly this many since we are
- saying, lay it out this way! Same for max and min nodes.
- Other than that just read in as many in the hostfile */
- if(opt.ntasks_set)
- count = opt.ntasks;
- else if(opt.nodes_set) {
- if(opt.max_nodes)
- count = opt.max_nodes;
- else if(opt.min_nodes)
- count = opt.min_nodes;
- }
- return verify_node_list(node_list_pptr, opt.distribution, count);
- }
- /*
- * print error message to stderr with opt.progname prepended
- */
- #undef USE_ARGERROR
- #if USE_ARGERROR
- static void argerror(const char *msg, ...)
- __attribute__ ((format (printf, 1, 2)));
- static void argerror(const char *msg, ...)
- {
- va_list ap;
- char buf[256];
- va_start(ap, msg);
- vsnprintf(buf, sizeof(buf), msg, ap);
- fprintf(stderr, "%s: %s\n",
- opt.progname ? opt.progname : "srun", buf);
- va_end(ap);
- }
- #else
- # define argerror error
- #endif /* USE_ARGERROR */
- /*
- * _opt_default(): used by initialize_and_process_args to set defaults
- */
- static void _opt_default()
- {
- char buf[MAXPATHLEN + 1];
- int i;
- uid_t uid = getuid();
- opt.user = uid_to_string(uid);
- if (strcmp(opt.user, "nobody") == 0)
- fatal("Invalid user id: %u", uid);
- opt.uid = uid;
- opt.gid = getgid();
- if ((getcwd(buf, MAXPATHLEN)) == NULL) {
- error("getcwd failed: %m");
- exit(error_exit);
- }
- opt.cwd = xstrdup(buf);
- opt.cwd_set = false;
- opt.progname = NULL;
- opt.ntasks = 1;
- opt.ntasks_set = false;
- opt.cpus_per_task = 0;
- opt.cpus_set = false;
- opt.min_nodes = 1;
- opt.max_nodes = 0;
- opt.sockets_per_node = NO_VAL; /* requested sockets */
- opt.cores_per_socket = NO_VAL; /* requested cores */
- opt.threads_per_core = NO_VAL; /* requested threads */
- opt.ntasks_per_node = NO_VAL; /* ntask max limits */
- opt.ntasks_per_socket = NO_VAL;
- opt.ntasks_per_core = NO_VAL;
- opt.nodes_set = false;
- opt.nodes_set_env = false;
- opt.nodes_set_opt = false;
- opt.cpu_bind_type = 0;
- opt.cpu_bind = NULL;
- opt.mem_bind_type = 0;
- opt.mem_bind = NULL;
- opt.time_limit = NO_VAL;
- opt.time_limit_str = NULL;
- opt.time_min = NO_VAL;
- opt.time_min_str = NULL;
- opt.ckpt_interval = 0;
- opt.ckpt_interval_str = NULL;
- opt.ckpt_dir = NULL;
- opt.restart_dir = NULL;
- opt.partition = NULL;
- opt.max_threads = MAX_THREADS;
- pmi_server_max_threads(opt.max_threads);
- opt.relative = NO_VAL;
- opt.relative_set = false;
- opt.resv_port_cnt = NO_VAL;
- opt.cmd_name = NULL;
- opt.job_name = NULL;
- opt.job_name_set_cmd = false;
- opt.job_name_set_env = false;
- opt.jobid = NO_VAL;
- opt.jobid_set = false;
- opt.dependency = NULL;
- opt.account = NULL;
- opt.comment = NULL;
- opt.qos = NULL;
- opt.distribution = SLURM_DIST_UNKNOWN;
- opt.plane_size = NO_VAL;
- opt.ofname = NULL;
- opt.ifname = NULL;
- opt.efname = NULL;
- opt.labelio = false;
- opt.unbuffered = false;
- opt.overcommit = false;
- opt.shared = (uint16_t)NO_VAL;
- opt.exclusive = false;
- opt.no_kill = false;
- opt.kill_bad_exit = NO_VAL;
- opt.immediate = 0;
- opt.join = false;
- opt.max_wait = slurm_get_wait_time();
- opt.quit_on_intr = false;
- opt.disable_status = false;
- opt.test_only = false;
- opt.preserve_env = false;
- opt.quiet = 0;
- _verbose = 0;
- opt.slurmd_debug = LOG_LEVEL_QUIET;
- opt.warn_signal = 0;
- opt.warn_time = 0;
- opt.pn_min_cpus = NO_VAL;
- opt.pn_min_memory = NO_VAL;
- opt.mem_per_cpu = NO_VAL;
- opt.pn_min_tmp_disk= NO_VAL;
- opt.hold = false;
- opt.constraints = NULL;
- opt.gres = NULL;
- opt.contiguous = false;
- opt.hostfile = NULL;
- opt.nodelist = NULL;
- opt.exc_nodes = NULL;
- opt.max_launch_time = 120;/* 120 seconds to launch job */
- opt.max_exit_timeout= 60; /* Warn user 60 seconds after task exit */
- /* Default launch msg timeout */
- opt.msg_timeout = slurm_get_msg_timeout();
- for (i=0; i<HIGHEST_DIMENSIONS; i++) {
- opt.conn_type[i] = (uint16_t) NO_VAL;
- opt.geometry[i] = (uint16_t) NO_VAL;
- }
- opt.reboot = false;
- opt.no_rotate = false;
- opt.blrtsimage = NULL;
- opt.linuximage = NULL;
- opt.mloaderimage = NULL;
- opt.ramdiskimage = NULL;
- opt.euid = (uid_t) -1;
- opt.egid = (gid_t) -1;
- opt.propagate = NULL; /* propagate specific rlimits */
- opt.prolog = slurm_get_srun_prolog();
- opt.epilog = slurm_get_srun_epilog();
- opt.begin = (time_t)0;
- opt.task_prolog = NULL;
- opt.task_epilog = NULL;
- /*
- * Reset some default values if running under a parallel debugger
- */
- if ((opt.parallel_debug = _under_parallel_debugger())) {
- opt.max_launch_time = 120;
- opt.max_threads = 1;
- pmi_server_max_threads(opt.max_threads);
- opt.msg_timeout = 15;
- }
- opt.pty = false;
- opt.open_mode = 0;
- opt.acctg_freq = -1;
- opt.cpu_freq = NO_VAL;
- opt.reservation = NULL;
- opt.wckey = NULL;
- opt.req_switch = -1;
- opt.wait4switch = -1;
- opt.launcher_opts = NULL;
- opt.launch_cmd = false;
- }
- /*---[ env var processing ]-----------------------------------------------*/
- /*
- * try to use a similar scheme as popt.
- *
- * in order to add a new env var (to be processed like an option):
- *
- * define a new entry into env_vars[], if the option is a simple int
- * or string you may be able to get away with adding a pointer to the
- * option to set. Otherwise, process var based on "type" in _opt_env.
- */
- struct env_vars {
- const char *var;
- int type;
- void *arg;
- void *set_flag;
- };
- env_vars_t env_vars[] = {
- {"SLURMD_DEBUG", OPT_INT, &opt.slurmd_debug, NULL },
- {"SLURM_ACCOUNT", OPT_STRING, &opt.account, NULL },
- {"SLURM_ACCTG_FREQ", OPT_INT, &opt.acctg_freq, NULL },
- {"SLURM_BLRTS_IMAGE", OPT_STRING, &opt.blrtsimage, NULL },
- {"SLURM_CHECKPOINT", OPT_STRING, &opt.ckpt_interval_str, NULL },
- {"SLURM_CHECKPOINT_DIR",OPT_STRING, &opt.ckpt_dir, NULL },
- {"SLURM_CNLOAD_IMAGE", OPT_STRING, &opt.linuximage, NULL },
- {"SLURM_CONN_TYPE", OPT_CONN_TYPE, NULL, NULL },
- {"SLURM_CPUS_PER_TASK", OPT_INT, &opt.cpus_per_task, &opt.cpus_set },
- {"SLURM_CPU_BIND", OPT_CPU_BIND, NULL, NULL },
- {"SLURM_CPU_FREQ_REQ", OPT_CPU_FREQ, NULL, NULL },
- {"SLURM_DEPENDENCY", OPT_STRING, &opt.dependency, NULL },
- {"SLURM_DISABLE_STATUS",OPT_INT, &opt.disable_status,NULL },
- {"SLURM_DISTRIBUTION", OPT_DISTRIB, NULL, NULL },
- {"SLURM_EPILOG", OPT_STRING, &opt.epilog, NULL },
- {"SLURM_EXCLUSIVE", OPT_EXCLUSIVE, NULL, NULL },
- {"SLURM_GEOMETRY", OPT_GEOMETRY, NULL, NULL },
- {"SLURM_GRES", OPT_STRING, &opt.gres, NULL },
- {"SLURM_IMMEDIATE", OPT_IMMEDIATE, NULL, NULL },
- {"SLURM_IOLOAD_IMAGE", OPT_STRING, &opt.ramdiskimage, NULL },
- /* SLURM_JOBID was used in slurm version 1.3 and below, it is now vestigial */
- {"SLURM_JOBID", OPT_INT, &opt.jobid, NULL },
- {"SLURM_JOB_ID", OPT_INT, &opt.jobid, NULL },
- {"SLURM_JOB_NAME", OPT_STRING, &opt.job_name, &opt.job_name_set_env},
- {"SLURM_KILL_BAD_EXIT", OPT_INT, &opt.kill_bad_exit, NULL },
- {"SLURM_LABELIO", OPT_INT, &opt.labelio, NULL },
- {"SLURM_LINUX_IMAGE", OPT_STRING, &opt.linuximage, NULL },
- {"SLURM_MEM_BIND", OPT_MEM_BIND, NULL, NULL },
- {"SLURM_MEM_PER_CPU", OPT_INT, &opt.mem_per_cpu, NULL },
- {"SLURM_MEM_PER_NODE", OPT_INT, &opt.pn_min_memory, NULL },
- {"SLURM_MLOADER_IMAGE", OPT_STRING, &opt.mloaderimage, NULL },
- {"SLURM_MPI_TYPE", OPT_MPI, NULL, NULL },
- {"SLURM_NCORES_PER_SOCKET",OPT_NCORES, NULL, NULL },
- {"SLURM_NETWORK", OPT_STRING, &opt.network, NULL },
- {"SLURM_NNODES", OPT_NODES, NULL, NULL },
- {"SLURM_NODELIST", OPT_STRING, &opt.alloc_nodelist,NULL },
- {"SLURM_NO_ROTATE", OPT_NO_ROTATE, NULL, NULL },
- {"SLURM_NTASKS", OPT_INT, &opt.ntasks, &opt.ntasks_set },
- {"SLURM_NPROCS", OPT_INT, &opt.ntasks, &opt.ntasks_set },
- {"SLURM_NSOCKETS_PER_NODE",OPT_NSOCKETS,NULL, NULL },
- {"SLURM_NTASKS_PER_NODE", OPT_INT, &opt.ntasks_per_node, NULL },
- {"SLURM_NTHREADS_PER_CORE",OPT_NTHREADS,NULL, NULL },
- {"SLURM_OPEN_MODE", OPT_OPEN_MODE, NULL, NULL },
- {"SLURM_OVERCOMMIT", OPT_OVERCOMMIT, NULL, NULL },
- {"SLURM_PARTITION", OPT_STRING, &opt.partition, NULL },
- {"SLURM_PROLOG", OPT_STRING, &opt.prolog, NULL },
- {"SLURM_QOS", OPT_STRING, &opt.qos, NULL },
- {"SLURM_RAMDISK_IMAGE", OPT_STRING, &opt.ramdiskimage, NULL },
- {"SLURM_REMOTE_CWD", OPT_STRING, &opt.cwd, NULL },
- {"SLURM_RESTART_DIR", OPT_STRING, &opt.restart_dir , NULL },
- {"SLURM_RESV_PORTS", OPT_RESV_PORTS, NULL, NULL },
- {"SLURM_SIGNAL", OPT_SIGNAL, NULL, NULL },
- {"SLURM_SRUN_MULTI", OPT_MULTI, NULL, NULL },
- {"SLURM_STDERRMODE", OPT_STRING, &opt.efname, NULL },
- {"SLURM_STDINMODE", OPT_STRING, &opt.ifname, NULL },
- {"SLURM_STDOUTMODE", OPT_STRING, &opt.ofname, NULL },
- {"SLURM_TASK_EPILOG", OPT_STRING, &opt.task_epilog, NULL },
- {"SLURM_TASK_PROLOG", OPT_STRING, &opt.task_prolog, NULL },
- {"SLURM_THREADS", OPT_INT, &opt.max_threads, NULL },
- {"SLURM_TIMELIMIT", OPT_STRING, &opt.time_limit_str,NULL },
- {"SLURM_UNBUFFEREDIO", OPT_INT, &opt.unbuffered, NULL },
- {"SLURM_WAIT", OPT_INT, &opt.max_wait, NULL },
- {"SLURM_WCKEY", OPT_STRING, &opt.wckey, NULL },
- {"SLURM_WORKING_DIR", OPT_STRING, &opt.cwd, &opt.cwd_set },
- {"SLURM_REQ_SWITCH", OPT_INT, &opt.req_switch, NULL },
- {"SLURM_WAIT4SWITCH", OPT_TIME_VAL, NULL, NULL },
- {NULL, 0, NULL, NULL}
- };
- /*
- * _opt_env(): used by initialize_and_process_args to set options via
- * environment variables. See comments above for how to
- * extend srun to process different vars
- */
- static void _opt_env()
- {
- char *val = NULL;
- env_vars_t *e = env_vars;
- while (e->var) {
- if ((val = getenv(e->var)) != NULL)
- _process_env_var(e, val);
- e++;
- }
- }
- static void
- _process_env_var(env_vars_t *e, const char *val)
- {
- char *end = NULL;
- task_dist_states_t dt;
- debug2("now processing env var %s=%s", e->var, val);
- if (e->set_flag) {
- *((bool *) e->set_flag) = true;
- }
- switch (e->type) {
- case OPT_STRING:
- *((char **) e->arg) = xstrdup(val);
- break;
- case OPT_INT:
- if (val != NULL) {
- *((int *) e->arg) = (int) strtol(val, &end, 10);
- if (!(end && *end == '\0')) {
- error("%s=%s invalid. ignoring...",
- e->var, val);
- }
- }
- break;
- case OPT_DISTRIB:
- if (strcmp(val, "unknown") == 0)
- break; /* ignore it, passed from salloc */
- dt = verify_dist_type(val, &opt.plane_size);
- if (dt == SLURM_DIST_UNKNOWN) {
- error("\"%s=%s\" -- invalid distribution type. "
- "ignoring...", e->var, val);
- } else
- opt.distribution = dt;
- break;
- case OPT_CPU_BIND:
- if (slurm_verify_cpu_bind(val, &opt.cpu_bind,
- &opt.cpu_bind_type))
- exit(error_exit);
- break;
- case OPT_CPU_FREQ:
- if (cpu_freq_verify_param(val, &opt.cpu_freq))
- error("Invalid --cpu-freq argument: %s. Ignored", val);
- break;
- case OPT_MEM_BIND:
- if (slurm_verify_mem_bind(val, &opt.mem_bind,
- &opt.mem_bind_type))
- exit(error_exit);
- break;
- case OPT_NODES:
- opt.nodes_set_env = get_resource_arg_range( val ,"OPT_NODES",
- &opt.min_nodes,
- &opt.max_nodes,
- false);
- if (opt.nodes_set_env == false) {
- error("\"%s=%s\" -- invalid node count. ignoring...",
- e->var, val);
- } else
- opt.nodes_set = opt.nodes_set_env;
- break;
- case OPT_OVERCOMMIT:
- opt.overcommit = true;
- break;
- case OPT_EXCLUSIVE:
- opt.exclusive = true;
- opt.shared = 0;
- break;
- case OPT_RESV_PORTS:
- if (val)
- opt.resv_port_cnt = strtol(val, NULL, 10);
- else
- opt.resv_port_cnt = 0;
- break;
- case OPT_OPEN_MODE:
- if ((val[0] == 'a') || (val[0] == 'A'))
- opt.open_mode = OPEN_MODE_APPEND;
- else if ((val[0] == 't') || (val[0] == 'T'))
- opt.open_mode = OPEN_MODE_TRUNCATE;
- else
- error("Invalid SLURM_OPEN_MODE: %s. Ignored", val);
- break;
- case OPT_CONN_TYPE:
- verify_conn_type(val, opt.conn_type);
- break;
- case OPT_NO_ROTATE:
- opt.no_rotate = true;
- break;
- case OPT_GEOMETRY:
- if (verify_geometry(val, opt.geometry)) {
- error("\"%s=%s\" -- invalid geometry, ignoring...",
- e->var, val);
- }
- break;
- case OPT_IMMEDIATE:
- if (val)
- opt.immediate = strtol(val, NULL, 10);
- else
- opt.immediate = DEFAULT_IMMEDIATE;
- break;
- case OPT_MPI:
- xfree(mpi_type);
- mpi_type = xstrdup(val);
- if (mpi_hook_client_init((char *)val) == SLURM_ERROR) {
- error("\"%s=%s\" -- invalid MPI type, "
- "--mpi=list for acceptable types.",
- e->var, val);
- exit(error_exit);
- }
- mpi_initialized = true;
- break;
- case OPT_SIGNAL:
- if (get_signal_opts((char *)val, &opt.warn_signal,
- &opt.warn_time)) {
- error("Invalid signal specification: %s", val);
- exit(error_exit);
- }
- break;
- case OPT_TIME_VAL:
- opt.wait4switch = time_str2secs(val);
- break;
- default:
- /* do nothing */
- break;
- }
- }
- /*
- * Get a decimal integer from arg.
- *
- * Returns the integer on success, exits program on failure.
- *
- */
- static int
- _get_int(const char *arg, const char *what, bool positive)
- {
- char *p;
- long int result = strtol(arg, &p, 10);
- if ((*p != '\0') || (result < 0L)
- || (positive && (result <= 0L))) {
- error ("Invalid numeric value \"%s\" for %s.", arg, what);
- exit(error_exit);
- } else if (result > INT_MAX) {
- error ("Numeric argument (%ld) to big for %s.", result, what);
- } else if (result < INT_MIN) {
- error ("Numeric argument %ld to small for %s.", result, what);
- }
- return (int) result;
- }
- static void set_options(const int argc, char **argv)
- {
- int opt_char, option_index = 0, max_val = 0, tmp_int;
- struct utsname name;
- static struct option long_options[] = {
- {"account", required_argument, 0, 'A'},
- {"extra-node-info", required_argument, 0, 'B'},
- {"cpus-per-task", required_argument, 0, 'c'},
- {"constraint", required_argument, 0, 'C'},
- {"dependency", required_argument, 0, 'd'},
- {"chdir", required_argument, 0, 'D'},
- {"error", required_argument, 0, 'e'},
- {"preserve-env", no_argument, 0, 'E'},
- {"preserve-slurm-env", no_argument, 0, 'E'},
- {"geometry", required_argument, 0, 'g'},
- {"hold", no_argument, 0, 'H'},
- {"input", required_argument, 0, 'i'},
- {"immediate", optional_argument, 0, 'I'},
- {"join", no_argument, 0, 'j'},
- {"job-name", required_argument, 0, 'J'},
- {"no-kill", no_argument, 0, 'k'},
- {"kill-on-bad-exit", optional_argument, 0, 'K'},
- {"label", no_argument, 0, 'l'},
- {"licenses", required_argument, 0, 'L'},
- {"distribution", required_argument, 0, 'm'},
- {"ntasks", required_argument, 0, 'n'},
- {"nodes", required_argument, 0, 'N'},
- {"output", required_argument, 0, 'o'},
- {"overcommit", no_argument, 0, 'O'},
- {"partition", required_argument, 0, 'p'},
- {"quit-on-interrupt", no_argument, 0, 'q'},
- {"quiet", no_argument, 0, 'Q'},
- {"relative", required_argument, 0, 'r'},
- {"no-rotate", no_argument, 0, 'R'},
- {"share", no_argument, 0, 's'},
- {"time", required_argument, 0, 't'},
- {"threads", required_argument, 0, 'T'},
- {"unbuffered", no_argument, 0, 'u'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"nodelist", required_argument, 0, 'w'},
- {"wait", required_argument, 0, 'W'},
- {"exclude", required_argument, 0, 'x'},
- {"disable-status", no_argument, 0, 'X'},
- {"no-allocate", no_argument, 0, 'Z'},
- {"acctg-freq", required_argument, 0, LONG_OPT_ACCTG_FREQ},
- {"alps", required_argument, 0, LONG_OPT_ALPS},
- {"begin", required_argument, 0, LONG_OPT_BEGIN},
- {"blrts-image", required_argument, 0, LONG_OPT_BLRTS_IMAGE},
- {"checkpoint", required_argument, 0, LONG_OPT_CHECKPOINT},
- {"checkpoint-dir", required_argument, 0, LONG_OPT_CHECKPOINT_DIR},
- {"cnload-image", required_argument, 0, LONG_OPT_LINUX_IMAGE},
- {"comment", required_argument, 0, LONG_OPT_COMMENT},
- {"conn-type", required_argument, 0, LONG_OPT_CONNTYPE},
- {"contiguous", no_argument, 0, LONG_OPT_CONT},
- {"cores-per-socket", required_argument, 0, LONG_OPT_CORESPERSOCKET},
- {"cpu_bind", required_argument, 0, LONG_OPT_CPU_BIND},
- {"cpu-freq", required_argument, 0, LONG_OPT_CPU_FREQ},
- {"debugger-test", no_argument, 0, LONG_OPT_DEBUG_TS},
- {"epilog", required_argument, 0, LONG_OPT_EPILOG},
- {"exclusive", no_argument, 0, LONG_OPT_EXCLUSIVE},
- {"get-user-env", optional_argument, 0, LONG_OPT_GET_USER_ENV},
- {"gid", required_argument, 0, LONG_OPT_GID},
- {"gres", required_argument, 0, LONG_OPT_GRES},
- {"help", no_argument, 0, LONG_OPT_HELP},
- {"hint", required_argument, 0, LONG_OPT_HINT},
- {"ioload-image", required_argument, 0, LONG_OPT_RAMDISK_IMAGE},
- {"jobid", required_argument, 0, LONG_OPT_JOBID},
- {"linux-image", required_argument, 0, LONG_OPT_LINUX_IMAGE},
- {"launch-cmd", no_argument, 0, LONG_OPT_LAUNCH_CMD},
- {"launcher-opts", required_argument, 0, LONG_OPT_LAUNCHER_OPTS},
- {"mail-type", required_argument, 0, LONG_OPT_MAIL_TYPE},
- {"mail-user", required_argument, 0, LONG_OPT_MAIL_USER},
- {"max-exit-timeout", required_argument, 0, LONG_OPT_XTO},
- {"max-launch-time", required_argument, 0, LONG_OPT_LAUNCH},
- {"mem", required_argument, 0, LONG_OPT_MEM},
- {"mem-per-cpu", required_argument, 0, LONG_OPT_MEM_PER_CPU},
- {"mem_bind", required_argument, 0, LONG_OPT_MEM_BIND},
- {"mincores", required_argument, 0, LONG_OPT_MINCORES},
- {"mincpus", required_argument, 0, LONG_OPT_MINCPUS},
- {"minsockets", required_argument, 0, LONG_OPT_MINSOCKETS},
- {"minthreads", required_argument, 0, LONG_OPT_MINTHREADS},
- {"mloader-image", required_argument, 0, LONG_OPT_MLOADER_IMAGE},
- {"mpi", required_argument, 0, LONG_OPT_MPI},
- {"msg-timeout", required_argument, 0, LONG_OPT_TIMEO},
- {"multi-prog", no_argument, 0, LONG_OPT_MULTI},
- {"network", required_argument, 0, LONG_OPT_NETWORK},
- {"nice", optional_argument, 0, LONG_OPT_NICE},
- {"ntasks-per-core", required_argument, 0, LONG_OPT_NTASKSPERCORE},
- {"ntasks-per-node", required_argument, 0, LONG_OPT_NTASKSPERNODE},
- {"ntasks-per-socket",required_argument, 0, LONG_OPT_NTASKSPERSOCKET},
- {"open-mode", required_argument, 0, LONG_OPT_OPEN_MODE},
- {"prolog", required_argument, 0, LONG_OPT_PROLOG},
- {"propagate", optional_argument, 0, LONG_OPT_PROPAGATE},
- {"pty", no_argument, 0, LONG_OPT_PTY},
- {"qos", required_argument, 0, LONG_OPT_QOS},
- {"ramdisk-image", required_argument, 0, LONG_OPT_RAMDISK_IMAGE},
- {"reboot", no_argument, 0, LONG_OPT_REBOOT},
- {"reservation", required_argument, 0, LONG_OPT_RESERVATION},
- {"restart-dir", required_argument, 0, LONG_OPT_RESTART_DIR},
- {"resv-ports", optional_argument, 0, LONG_OPT_RESV_PORTS},
- {"runjob-opts", required_argument, 0, LONG_OPT_LAUNCHER_OPTS},
- {"signal", required_argument, 0, LONG_OPT_SIGNAL},
- {"slurmd-debug", required_argument, 0, LONG_OPT_DEBUG_SLURMD},
- {"sockets-per-node", required_argument, 0, LONG_OPT_SOCKETSPERNODE},
- {"switches", required_argument, 0, LONG_OPT_REQ_SWITCH},
- {"task-epilog", required_argument, 0, LONG_OPT_TASK_EPILOG},
- {"task-prolog", required_argument, 0, LONG_OPT_TASK_PROLOG},
- {"tasks-per-node", required_argument, 0, LONG_OPT_NTASKSPERNODE},
- {"test-only", no_argument, 0, LONG_OPT_TEST_ONLY},
- {"time-min", required_argument, 0, LONG_OPT_TIME_MIN},
- {"threads-per-core", required_argument, 0, LONG_OPT_THREADSPERCORE},
- {"tmp", required_argument, 0, LONG_OPT_TMP},
- {"uid", required_argument, 0, LONG_OPT_UID},
- {"usage", no_argument, 0, LONG_OPT_USAGE},
- {"wckey", required_argument, 0, LONG_OPT_WCKEY},
- {NULL, 0, 0, 0}
- };
- char *opt_string = "+A:B:c:C:d:D:e:Eg:hHi:I::jJ:kK::lL:m:n:N:"
- "o:Op:P:qQr:Rst:T:uU:vVw:W:x:XZ";
- char *pos_delimit;
- #ifdef HAVE_PTY_H
- char *tmp_str;
- #endif
- struct option *optz = spank_option_table_create (long_options);
- if (!optz) {
- error("Unable to create option table");
- exit(error_exit);
- }
- if (opt.progname == NULL)
- opt.progname = xbasename(argv[0]);
- else
- error("opt.progname is already set.");
- optind = 0;
- while((opt_char = getopt_long(argc, argv, opt_string,
- optz, &option_index)) != -1) {
- switch (opt_char) {
- case (int)'?':
- fprintf(stderr,
- "Try \"srun --help\" for more information\n");
- exit(error_exit);
- break;
- case (int)'A':
- case (int)'U': /* backwards compatibility */
- xfree(opt.account);
- opt.account = xstrdup(optarg);
- break;
- case (int)'B':
- opt.extra_set = verify_socket_core_thread_count(
- optarg,
- &opt.sockets_per_node,
- &opt.cores_per_socket,
- &opt.threads_per_core,
- &opt.cpu_bind_type);
- if (opt.extra_set == false) {
- error("invalid resource allocation -B `%s'",
- optarg);
- exit(error_exit);
- }
- break;
- case (int)'c':
- tmp_int = _get_int(optarg, "cpus-per-task", false);
- if (opt.cpus_set && (tmp_int > opt.cpus_per_task)) {
- info("Job step's --cpus-per-task value exceeds"
- " that of job (%d > %d). Job step may "
- "never run.", tmp_int, opt.cpus_per_task);
- }
- opt.cpus_set = true;
- opt.cpus_per_task = tmp_int;
- break;
- case (int)'C':
- xfree(opt.constraints);
- opt.constraints = xstrdup(optarg);
- break;
- case (int)'d':
- xfree(opt.dependency);
- opt.dependency = xstrdup(optarg);
- break;
- case (int)'D':
- opt.cwd_set = true;
- xfree(opt.cwd);
- opt.cwd = xstrdup(optarg);
- break;
- case (int)'e':
- if (opt.pty) {
- fatal("--error incompatible with --pty "
- "option");
- exit(error_exit);
- }
- xfree(opt.efname);
- if (strcasecmp(optarg, "none") == 0)
- opt.efname = xstrdup("/dev/null");
- else
- opt.efname = xstrdup(optarg);
- break;
- case (int)'E':
- opt.preserve_env = true;
- break;
- case (int)'g':
- if (verify_geometry(optarg, opt.geometry))
- exit(error_exit);
- break;
- case (int)'H':
- opt.hold = true;
- break;
- case (int)'i':
- if (opt.pty) {
- fatal("--input incompatible with "
- "--pty option");
- exit(error_exit);
- }
- xfree(opt.ifname);
- if (strcasecmp(optarg, "none") == 0)
- opt.ifname = xstrdup("/dev/null");
- else
- opt.ifname = xstrdup(optarg);
- break;
- case (int)'I':
- if (optarg)
- opt.immediate = strtol(optarg, NULL, 10);
- else
- opt.immediate = DEFAULT_IMMEDIATE;
- break;
- case (int)'j':
- opt.join = true;
- break;
- case (int)'J':
- opt.job_name_set_cmd = true;
- xfree(opt.job_name);
- opt.job_name = xstrdup(optarg);
- break;
- case (int)'k':
- opt.no_kill = true;
- break;
- case (int)'K':
- if (optarg)
- opt.kill_bad_exit = strtol(optarg, NULL, 10);
- else
- opt.kill_bad_exit = 1;
- break;
- case (int)'l':
- opt.labelio = true;
- break;
- case 'L':
- xfree(opt.licenses);
- opt.licenses = xstrdup(optarg);
- break;
- case (int)'m':
- opt.distribution = verify_dist_type(optarg,
- &opt.plane_size);
- if (opt.distribution == SLURM_DIST_UNKNOWN) {
- error("distribution type `%s' "
- "is not recognized", optarg);
- exit(error_exit);
- }
- break;
- case (int)'n':
- opt.ntasks_set = true;
- opt.ntasks =
- _get_int(optarg, "number of tasks", true);
- break;
- case (int)'N':
- opt.nodes_set_opt =
- get_resource_arg_range( optarg,
- "requested node count",
- &opt.min_nodes,
- &opt.max_nodes, true );
- if (opt.nodes_set_opt == false) {
- error("invalid resource allocation -N `%s'",
- optarg);
- exit(error_exit);
- } else
- opt.nodes_set = opt.nodes_set_opt;
- break;
- case (int)'o':
- if (opt.pty) {
- error("--output incompatible with --pty "
- "option");
- exit(error_exit);
- }
- xfree(opt.ofname);
- if (strcasecmp(optarg, "none") == 0)
- opt.ofname = xstrdup("/dev/null");
- else
- opt.ofname = xstrdup(optarg);
- break;
- case (int)'O':
- opt.overcommit = true;
- break;
- case (int)'p':
- xfree(opt.partition);
- opt.partition = xstrdup(optarg);
- break;
- case (int)'P':
- verbose("-P option is deprecated, use -d instead");
- xfree(opt.dependency);
- opt.dependency = xstrdup(optarg);
- break;
- case (int)'q':
- opt.quit_on_intr = true;
- break;
- case (int) 'Q':
- opt.quiet++;
- break;
- case (int)'r':
- opt.relative = _get_int(optarg, "relative", false);
- opt.relative_set = true;
- break;
- case (int)'R':
- opt.no_rotate = true;
- break;
- case (int)'s':
- opt.shared = 1;
- break;
- case (int)'t':
- xfree(opt.time_limit_str);
- opt.time_limit_str = xstrdup(optarg);
- break;
- case (int)'T':
- opt.max_threads =
- _get_int(optarg, "max_threads", true);
- pmi_server_max_threads(opt.max_threads);
- break;
- case (int)'u':
- opt.unbuffered = true;
- break;
- case (int)'v':
- _verbose++;
- break;
- case (int)'V':
- print_slurm_version();
- exit(0);
- break;
- case (int)'w':
- xfree(opt.nodelist);
- opt.nodelist = xstrdup(optarg);
- break;
- case (int)'W':
- opt.max_wait = _get_int(optarg, "wait", false);
- break;
- case (int)'x':
- xfree(opt.exc_nodes);
- opt.exc_nodes = xstrdup(optarg);
- if (!_valid_node_list(&opt.exc_nodes))
- exit(error_exit);
- break;
- case (int)'X':
- opt.disable_status = true;
- break;
- case (int)'Z':
- opt.no_alloc = true;
- uname(&name);
- if (strcasecmp(name.sysname, "AIX") == 0)
- opt.network = xstrdup("ip");
- break;
- case LONG_OPT_CONT:
- opt.contiguous = true;
- break;
- case LONG_OPT_EXCLUSIVE:
- opt.exclusive = true;
- opt.shared = 0;
- break;
- case LONG_OPT_CPU_BIND:
- if (slurm_verify_cpu_bind(optarg, &opt.cpu_bind,
- &opt.cpu_bind_type))
- exit(error_exit);
- break;
- case LONG_OPT_LAUNCH_CMD:
- opt.launch_cmd = true;
- break;
- case LONG_OPT_MEM_BIND:
- if (slurm_verify_mem_bind(optarg, &opt.mem_bind,
- &opt.mem_bind_type))
- exit(error_exit);
- break;
- case LONG_OPT_MINCPUS:
- opt.pn_min_cpus = _get_int(optarg, "mincpus", true);
- break;
- case LONG_OPT_MINCORES:
- verbose("mincores option has been deprecated, use "
- "cores-per-socket");
- opt.cores_per_socket = _get_int(optarg,
- "mincores", true);
- if (opt.cores_per_socket < 0) {
- error("invalid mincores constraint %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MINSOCKETS:
- verbose("minsockets option has been deprecated, use "
- "sockets-per-node");
- opt.sockets_per_node = _get_int(optarg,
- "minsockets",true);
- if (opt.sockets_per_node < 0) {
- error("invalid minsockets constraint %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MINTHREADS:
- verbose("minthreads option has been deprecated, use "
- "threads-per-core");
- opt.threads_per_core = _get_int(optarg,
- "minthreads",true);
- if (opt.threads_per_core < 0) {
- error("invalid minthreads constraint %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MEM:
- opt.pn_min_memory = (int) str_to_mbytes(optarg);
- if (opt.pn_min_memory < 0) {
- error("invalid memory constraint %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MEM_PER_CPU:
- opt.mem_per_cpu = (int) str_to_mbytes(optarg);
- if (opt.mem_per_cpu < 0) {
- error("invalid memory constraint %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MPI:
- xfree(mpi_type);
- mpi_type = xstrdup(optarg);
- if (mpi_hook_client_init((char *)optarg)
- == SLURM_ERROR) {
- error("\"--mpi=%s\" -- long invalid MPI type, "
- "--mpi=list for acceptable types.",
- optarg);
- exit(error_exit);
- }
- mpi_initialized = true;
- break;
- case LONG_OPT_RESV_PORTS:
- if (optarg)
- opt.resv_port_cnt = strtol(optarg, NULL, 10);
- else
- opt.resv_port_cnt = 0;
- break;
- case LONG_OPT_TMP:
- opt.pn_min_tmp_disk = str_to_mbytes(optarg);
- if (opt.pn_min_tmp_disk < 0) {
- error("invalid tmp value %s", optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_JOBID:
- opt.jobid = _get_int(optarg, "jobid", true);
- opt.jobid_set = true;
- break;
- case LONG_OPT_TIMEO:
- opt.msg_timeout =
- _get_int(optarg, "msg-timeout", true);
- break;
- case LONG_OPT_LAUNCH:
- opt.max_launch_time =
- _get_int(optarg, "max-launch-time", true);
- break;
- case LONG_OPT_XTO:
- opt.max_exit_timeout =
- _get_int(optarg, "max-exit-timeout", true);
- break;
- case LONG_OPT_UID:
- if (opt.euid != (uid_t) -1) {
- error("duplicate --uid option");
- exit(error_exit);
- }
- if (uid_from_string (optarg, &opt.euid) < 0) {
- error("--uid=\"%s\" invalid", optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_GID:
- if (opt.egid != (gid_t) -1) {
- error("duplicate --gid option");
- exit(error_exit);
- }
- if (gid_from_string (optarg, &opt.egid) < 0) {
- error("--gid=\"%s\" invalid", optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_DEBUG_SLURMD:
- opt.slurmd_debug =
- _get_int(optarg, "slurmd-debug", false);
- break;
- case LONG_OPT_DEBUG_TS:
- opt.debugger_test = true;
- /* make other parameters look like debugger
- * is really attached */
- opt.parallel_debug = true;
- opt.max_launch_time = 120;
- opt.max_threads = 1;
- pmi_server_max_threads(opt.max_threads);
- opt.msg_timeout = 15;
- break;
- case 'h':
- case LONG_OPT_HELP:
- _help();
- exit(0);
- case LONG_OPT_USAGE:
- _usage();
- exit(0);
- case LONG_OPT_CONNTYPE:
- verify_conn_type(optarg, opt.conn_type);
- break;
- case LONG_OPT_TEST_ONLY:
- opt.test_only = true;
- break;
- case LONG_OPT_NETWORK:
- xfree(opt.network);
- opt.network = xstrdup(optarg);
- setenv("SLURM_NETWORK", opt.network, 1);
- break;
- case LONG_OPT_PROPAGATE:
- xfree(opt.propagate);
- if (optarg)
- opt.propagate = xstrdup(optarg);
- else
- opt.propagate = xstrdup("ALL");
- break;
- case LONG_OPT_PROLOG:
- xfree(opt.prolog);
- opt.prolog = xstrdup(optarg);
- break;
- case LONG_OPT_EPILOG:
- xfree(opt.epilog);
- opt.epilog = xstrdup(optarg);
- break;
- case LONG_OPT_BEGIN:
- opt.begin = parse_time(optarg, 0);
- if (errno == ESLURM_INVALID_TIME_VALUE) {
- error("Invalid time specification %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MAIL_TYPE:
- opt.mail_type |= parse_mail_type(optarg);
- if (opt.mail_type == 0) {
- error("--mail-type=%s invalid", optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_MAIL_USER:
- xfree(opt.mail_user);
- opt.mail_user = xstrdup(optarg);
- break;
- case LONG_OPT_TASK_PROLOG:
- xfree(opt.task_prolog);
- opt.task_prolog = xstrdup(optarg);
- break;
- case LONG_OPT_TASK_EPILOG:
- xfree(opt.task_epilog);
- opt.task_epilog = xstrdup(optarg);
- break;
- case LONG_OPT_NICE:
- if (optarg)
- opt.nice = strtol(optarg, NULL, 10);
- else
- opt.nice = 100;
- if (abs(opt.nice) > NICE_OFFSET) {
- error("Invalid nice value, must be between "
- "-%d and %d", NICE_OFFSET, NICE_OFFSET);
- exit(error_exit);
- }
- if (opt.nice < 0) {
- uid_t my_uid = getuid();
- if ((my_uid != 0) &&
- (my_uid != slurm_get_slurm_user_id())) {
- error("Nice value must be non-negative, "
- "value ignored");
- opt.nice = 0;
- }
- }
- break;
- case LONG_OPT_MULTI:
- opt.multi_prog = true;
- break;
- case LONG_OPT_COMMENT:
- xfree(opt.comment);
- opt.comment = xstrdup(optarg);
- break;
- case LONG_OPT_QOS:
- xfree(opt.qos);
- opt.qos = xstrdup(optarg);
- break;
- case LONG_OPT_SOCKETSPERNODE:
- max_val = 0;
- get_resource_arg_range( optarg, "sockets-per-node",
- &opt.sockets_per_node,
- &max_val, true );
- if ((opt.sockets_per_node == 1) &&
- (max_val == INT_MAX))
- opt.sockets_per_node = NO_VAL;
- break;
- case LONG_OPT_CORESPERSOCKET:
- max_val = 0;
- get_resource_arg_range( optarg, "cores-per-socket",
- &opt.cores_per_socket,
- &max_val, true );
- if ((opt.cores_per_socket == 1) &&
- (max_val == INT_MAX))
- opt.cores_per_socket = NO_VAL;
- break;
- case LONG_OPT_THREADSPERCORE:
- max_val = 0;
- get_resource_arg_range( optarg, "threads-per-core",
- &opt.threads_per_core,
- &max_val, true );
- if ((opt.threads_per_core == 1) &&
- (max_val == INT_MAX))
- opt.threads_per_core = NO_VAL;
- break;
- case LONG_OPT_NTASKSPERNODE:
- opt.ntasks_per_node = _get_int(optarg, "ntasks-per-node",
- true);
- break;
- case LONG_OPT_NTASKSPERSOCKET:
- opt.ntasks_per_socket = _get_int(optarg,
- "ntasks-per-socket", true);
- break;
- case LONG_OPT_NTASKSPERCORE:
- opt.ntasks_per_core = _get_int(optarg, "ntasks-per-core",
- true);
- break;
- case LONG_OPT_HINT:
- /* Keep after other options filled in */
- if (verify_hint(optarg,
- &opt.sockets_per_node,
- &opt.cores_per_socket,
- &opt.threads_per_core,
- &opt.ntasks_per_core,
- &opt.cpu_bind_type)) {
- exit(error_exit);
- }
- break;
- case LONG_OPT_BLRTS_IMAGE:
- xfree(opt.blrtsimage);
- opt.blrtsimage = xstrdup(optarg);
- break;
- case LONG_OPT_LINUX_IMAGE:
- xfree(opt.linuximage);
- opt.linuximage = xstrdup(optarg);
- break;
- case LONG_OPT_MLOADER_IMAGE:
- xfree(opt.mloaderimage);
- opt.mloaderimage = xstrdup(optarg);
- break;
- case LONG_OPT_RAMDISK_IMAGE:
- xfree(opt.ramdiskimage);
- opt.ramdiskimage = xstrdup(optarg);
- break;
- case LONG_OPT_REBOOT:
- opt.reboot = true;
- break;
- case LONG_OPT_GET_USER_ENV:
- error("--get-user-env is no longer supported in srun, "
- "use sbatch");
- break;
- case LONG_OPT_PTY:
- #ifdef HAVE_PTY_H
- opt.pty = true;
- opt.unbuffered = true; /* implicit */
- if (opt.ifname)
- tmp_str = "--input";
- else if (opt.ofname)
- tmp_str = "--output";
- else if (opt.efname)
- tmp_str = "--error";
- else
- tmp_str = NULL;
- if (tmp_str) {
- error("%s incompatible with --pty option",
- tmp_str);
- exit(error_exit);
- }
- #else
- error("--pty not currently supported on this system "
- "type");
- #endif
- break;
- case LONG_OPT_CHECKPOINT:
- xfree(opt.ckpt_interval_str);
- opt.ckpt_interval_str = xstrdup(optarg);
- break;
- case LONG_OPT_OPEN_MODE:
- if ((optarg[0] == 'a') || (optarg[0] == 'A'))
- opt.open_mode = OPEN_MODE_APPEND;
- else if ((optarg[0] == 't') || (optarg[0] == 'T'))
- opt.open_mode = OPEN_MODE_TRUNCATE;
- else {
- error("Invalid --open-mode argument: %s. Ignored",
- optarg);
- }
- break;
- case LONG_OPT_ACCTG_FREQ:
- opt.acctg_freq = _get_int(optarg, "acctg-freq",
- false);
- break;
- case LONG_OPT_CPU_FREQ:
- if (cpu_freq_verify_param(optarg, &opt.cpu_freq))
- error("Invalid --cpu-freq argument: %s. Ignored",
- optarg);
- break;
- case LONG_OPT_WCKEY:
- xfree(opt.wckey);
- opt.wckey = xstrdup(optarg);
- break;
- case LONG_OPT_RESERVATION:
- xfree(opt.reservation);
- opt.reservation = xstrdup(optarg);
- break;
- case LONG_OPT_LAUNCHER_OPTS:
- xfree(opt.launcher_opts);
- opt.launcher_opts = xstrdup(optarg);
- break;
- case LONG_OPT_CHECKPOINT_DIR:
- xfree(opt.ckpt_dir);
- opt.ckpt_dir = xstrdup(optarg);
- break;
- case LONG_OPT_RESTART_DIR:
- xfree(opt.restart_dir);
- opt.restart_dir = xstrdup(optarg);
- break;
- case LONG_OPT_SIGNAL:
- if (get_signal_opts(optarg, &opt.warn_signal,
- &opt.warn_time)) {
- error("Invalid signal specification: %s",
- optarg);
- exit(error_exit);
- }
- break;
- case LONG_OPT_TIME_MIN:
- xfree(opt.time_min_str);
- opt.time_min_str = xstrdup(optarg);
- break;
- case LONG_OPT_GRES:
- if (!strcasecmp(optarg, "help") ||
- !strcasecmp(optarg, "list")) {
- print_gres_help();
- exit(0);
- }
- xfree(opt.gres);
- opt.gres = xstrdup(optarg);
- break;
- case LONG_OPT_ALPS:
- verbose("Not running ALPS. --alps option ignored.");
- break;
- case LONG_OPT_REQ_SWITCH:
- pos_delimit = strstr(optarg,"@");
- if (pos_delimit != NULL) {
- pos_delimit[0] = '\0';
- pos_delimit++;
- opt.wait4switch = time_str2secs(pos_delimit);
- }
- opt.req_switch = _get_int(optarg, "switches",
- true);
- break;
- default:
- if (spank_process_option (opt_char, optarg) < 0) {
- exit(error_exit);
- }
- }
- }
- spank_option_table_destroy (optz);
- }
- #if defined HAVE_BG && !defined HAVE_BG_L_P
- static bool _check_is_pow_of_2(int32_t n) {
- /* Bitwise ANDing a power of 2 number like 16 with its
- * negative (-16) gives itself back. Only integers which are power of
- * 2 behave like that.
- */
- return ((n!=0) && (n&(-n))==n);
- }
- extern void bg_figure_nodes_tasks()
- {
- /* A bit of setup for IBM's runjob. runjob only has so many
- options, so it isn't that bad.
- */
- int32_t node_cnt;
- if (opt.max_nodes)
- node_cnt = opt.max_nodes;
- else
- node_cnt = opt.min_nodes;
- if (!opt.ntasks_set) {
- if (opt.ntasks_per_node != NO_VAL)
- opt.ntasks = node_cnt * opt.ntasks_per_node;
- else {
- opt.ntasks = node_cnt;
- opt.ntasks_per_node = 1;
- }
- opt.ntasks_set = true;
- } else {
- int32_t ntpn;
- bool figured = false;
- if (opt.nodes_set) {
- if (node_cnt > opt.ntasks) {
- if (opt.nodes_set_opt)
- info("You asked for %d nodes, "
- "but only %d tasks, resetting "
- "node count to %u.",
- node_cnt, opt.ntasks, opt.ntasks);
- opt.max_nodes = opt.min_nodes = node_cnt
- = opt.ntasks;
- }
- }
- /* If nodes not set do not try to set min/max nodes
- yet since that would result in an incorrect
- allocation. For a step allocation it is figured
- out later in srun_job.c _job_create_structure().
- */
- if (!opt.ntasks_per_node || (opt.ntasks_per_node == NO_VAL)) {
- /* We always want the next larger number if
- there is a fraction so we try to stay in
- the allocation requested.
- */
- opt.ntasks_per_node =
- (opt.ntasks + node_cnt - 1) / node_cnt;
- figured = true;
- }
- /* On a Q we need ntasks_per_node to be a multiple of 2 */
- ntpn = opt.ntasks_per_node;
- while (!_check_is_pow_of_2(ntpn))
- ntpn++;
- if (!figured && (ntpn != opt.ntasks_per_node)) {
- info("You requested --ntasks-per-node=%d, which is not "
- "a power of 2. Setting --ntasks-per-node=%d "
- "for you.", opt.ntasks_per_node, ntpn);
- figured = true;
- }
- opt.ntasks_per_node = ntpn;
- ntpn = opt.ntasks / opt.ntasks_per_node;
- /* Make sure we are requesting the correct number of nodes. */
- if (node_cnt < ntpn) {
- opt.max_nodes = opt.min_nodes = ntpn;
- if (opt.nodes_set && !figured) {
- fatal("You requested -N %d and -n %d "
- "with --ntasks-per-node=%d. "
- "This isn't a valid request.",
- node_cnt, opt.ntasks,
- opt.ntasks_per_node);
- }
- node_cnt = opt.max_nodes;
- }
- /* Do this again to make sure we have a legitimate
- ratio. */
- ntpn = opt.ntasks_per_node;
- if ((node_cnt * ntpn) < opt.ntasks) {
- ntpn++;
- while (!_check_is_pow_of_2(ntpn))
- ntpn++;
- if (!figured && (ntpn != opt.ntasks_per_node))
- info("You requested --ntasks-per-node=%d, "
- "which cannot spread across %d nodes "
- "correctly. Setting --ntasks-per-node=%d "
- "for you.",
- opt.ntasks_per_node, node_cnt, ntpn);
- opt.ntasks_per_node = ntpn;
- }
- if (opt.nodes_set) {
- if ((opt.ntasks_per_node != 1)
- && (opt.ntasks_per_node != 2)
- && (opt.ntasks_per_node != 4)
- && (opt.ntasks_per_node != 8)
- && (opt.ntasks_per_node != 16)
- && (opt.ntasks_per_node != 32)
- && (opt.ntasks_per_node != 64))
- fatal("You requested -N %d and -n %d "
- "which gives --ntasks-per-node=%d. "
- "This isn't a valid request.",
- node_cnt, opt.n…
Large files files are truncated, but you can click here to view the full file