diff --git a/NEWS b/NEWS index ea26b45cd81be71c93c972e3087792fe4145237f..af30aed7bb637260e1068ed28466759430e3b3c6 100644 --- a/NEWS +++ b/NEWS @@ -79,17 +79,17 @@ documents those changes that are of interest to users and admins. * Changes in SLURM 1.2.19 ========================= -*** IMPORTANT CHANGE IN RPM BUILD BELOW **** - -- slurm.spec file (used to build RPMs) updated in order to support Mock, a - chroot build environment, see https://hosted.fedoraproject.org/projects/mock/ +*** NOTE IMPORTANT CHANGE IN RPM BUILD BELOW **** + -- slurm.spec file (used to build RPMs) was updated in order to support Mock, a + chroot build environment. See https://hosted.fedoraproject.org/projects/mock/ for more information. The following RPMs are no longer build by default: - aix-federation, auth_none, authd, bluegene, sgijob. switch-elan. Change the - RPMs built using the following options in ~/rpmmacros: "%_with_authd 1", + aix-federation, auth_none, authd, bluegene, sgijob, and switch-elan. Change + the RPMs built using the following options in ~/rpmmacros: "%_with_authd 1", "%_without_munge 1", etc. See the slurm.spec file for more details. -- Print warning if non-privileged user requests negative "--nice" value on job submission (srun, salloc, and sbatch commands). - -- In sched/wiki and sched/wiki2, add support for srun's - --ntasks-per-node option. + -- In sched/wiki and sched/wiki2, add support for srun's --ntasks-per-node + option. -- In select/bluegene with Groups defined for Images, fix possible memory corruption. Other configurations are not affected. -- BLUEGENE - Fix bug that prevented user specification of linux-image, @@ -105,6 +105,10 @@ documents those changes that are of interest to users and admins. -- If srun --output or --error specification contains a task number rather than a file name, send stdout/err from specified task to srun's stdout/err rather than to a file by the same name as the task's number. + -- For srun --multi-prog option, verify configuration file before attempting + to launch tasks, report clear explanation of any configuration file errors. + -- For sched/wiki2, add optional timeout option to srun's s --get-user-env + parameter, change default timeout from 3 to 8 seconds. * Changes in SLURM 1.2.18 ========================= diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1 index bfacb42c641ca7242810a81d2f789274d2b86a78..61a35ec6fcd2c0f6babe1ef083fa1072150a2fbf 100644 --- a/doc/man/man1/sbatch.1 +++ b/doc/man/man1/sbatch.1 @@ -154,13 +154,14 @@ The order of the node names in the list is not important; the node names will be sorted my SLURM. .TP -\fB\-\-get\-user\-env\fR +\fB\-\-get\-user\-env\fR[=\fItimeout\fR] This option will tell sbatch to retrieve the login environment variables for the user specified in the \-\-uid option. The environment variables are retrieved by running "su - <username> -c /usr/bin/env" and parsing the output. Be aware that any environment variables already set in sbatch's environment will take precedence over any environment variables in the user's login environment. +Optional timeout value is in seconds. Default value is 8 seconds. NOTE: This option only works if the caller has an effective uid of "root". This option was originally created for use by Moab. diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1 index a5afedb093c238ac8aff8841b91ca02fa0282dc0..7576aefefb4bf86a9d7e76043c1d5bdb87daf4a3 100644 --- a/doc/man/man1/srun.1 +++ b/doc/man/man1/srun.1 @@ -1348,9 +1348,13 @@ space: Task rank One or more task ranks to use this configuration. Multiple values may be comma separated. -Ranges may be indicated with two numbers separated with a '\-'. +Ranges may be indicated with two numbers separated with a '\-' with +the smaller number first (e.g. "0\-4" and not "4\-0"). To indicate all tasks, specify a rank of '*' (in which case you probably should not be using this option). +If an attempt is made to initiate a task for which no executable +program is defined, the following error message will be produced +"No executable program specified for this task". .TP Executable The name of the program to execute. diff --git a/src/common/env.c b/src/common/env.c index d0098eb1ff39c56b6cd9ecbff44ee550391b8cd9..fa945bb91d4fa9a80f332024a4707514eb9b4a1c 100644 --- a/src/common/env.c +++ b/src/common/env.c @@ -75,7 +75,7 @@ strong_alias(env_array_append_fmt, slurm_env_array_append_fmt); strong_alias(env_array_overwrite, slurm_env_array_overwrite); strong_alias(env_array_overwrite_fmt, slurm_env_array_overwrite_fmt); -#define SU_WAIT_MSEC 3000 /* 3000 msec for /bin/su to return user +#define SU_WAIT_MSEC 8000 /* 8000 msec for /bin/su to return user * env vars for --get-user-env option */ /* * Return pointer to `name' entry in environment if found, or @@ -1239,12 +1239,13 @@ static void _strip_cr_nl(char *line) * environment variables, as determined by calling (more-or-less) * "/bin/su - <username> -c /usr/bin/env". * + * timeout value is in seconds or zero for default (8 secs) * On error, returns NULL. * * NOTE: The calling process must have an effective uid of root for * this function to succeed. */ -char **env_array_user_default(const char *username) +char **env_array_user_default(const char *username, int timeout) { FILE *su; char line[BUFSIZ]; @@ -1283,13 +1284,7 @@ char **env_array_user_default(const char *username) snprintf(cmdstr, sizeof(cmdstr), "echo; echo; echo; echo %s; env; echo %s", starttoken, stoptoken); -#if 0 - /* execute .profile only */ - execl("/bin/su", "su", username, "-c", cmdstr, NULL); -#else - /* execute .login plus .profile */ execl("/bin/su", "su", "-", username, "-c", cmdstr, NULL); -#endif exit(1); } @@ -1307,7 +1302,10 @@ char **env_array_user_default(const char *username) found = 0; while (!found) { gettimeofday(&now, NULL); - timeleft = SU_WAIT_MSEC; + if (timeout > 0) + timeleft = timeout * 1000; + else + timeleft = SU_WAIT_MSEC; timeleft -= (now.tv_sec - begin.tv_sec) * 1000; timeleft -= (now.tv_usec - begin.tv_usec) / 1000; if (timeleft <= 0) @@ -1343,7 +1341,10 @@ char **env_array_user_default(const char *username) found = 0; while (!found) { gettimeofday(&now, NULL); - timeleft = SU_WAIT_MSEC; + if (timeout > 0) + timeleft = timeout * 1000; + else + timeleft = SU_WAIT_MSEC; timeleft -= (now.tv_sec - begin.tv_sec) * 1000; timeleft -= (now.tv_usec - begin.tv_usec) / 1000; if (timeleft <= 0) diff --git a/src/common/env.h b/src/common/env.h index 4b535380c4b2645354613efeee80b83a214ab309..c62e0054593ef4cc89e366db8be68952b67f2a9d 100644 --- a/src/common/env.h +++ b/src/common/env.h @@ -244,11 +244,12 @@ void env_array_set_environment(char **env_array); * environment variables, as determined by calling (more-or-less) * "/bin/su - <username> -c /usr/bin/env". * + * timeout value is in seconds or zero for default (8 secs) * On error, returns NULL. * * NOTE: The calling process must have an effective uid of root for * this function to succeed. */ -char **env_array_user_default(const char *username); +char **env_array_user_default(const char *username, int timeout); #endif diff --git a/src/plugins/sched/wiki2/start_job.c b/src/plugins/sched/wiki2/start_job.c index a6afae77f0f69e1d757a3ffb4be13107daf00878..f7cdd46d189ad8b080c780beb3ac794e7a9ca0ee 100644 --- a/src/plugins/sched/wiki2/start_job.c +++ b/src/plugins/sched/wiki2/start_job.c @@ -243,21 +243,6 @@ static int _start_job(uint32_t jobid, int task_cnt, char *hostlist, lock_slurmctld(job_write_lock); if (job_ptr->job_id != jobid) job_ptr = find_job_record(jobid); - if (job_ptr && (job_ptr->job_id == jobid) && job_ptr->details && - (job_ptr->job_state == JOB_RUNNING)) { - /* Restore required node list, even if job has started so - * that it can be requeued with the original requirements */ - xfree(job_ptr->details->req_nodes); - job_ptr->details->req_nodes = save_req_nodes; - FREE_NULL_BITMAP(job_ptr->details->req_node_bitmap); - job_ptr->details->req_node_bitmap = save_req_bitmap; - FREE_NULL_BITMAP(job_ptr->details->exc_node_bitmap); - } else { - xfree(save_req_nodes); - FREE_NULL_BITMAP(save_req_bitmap); - if (job_ptr && (job_ptr->job_id == jobid) && job_ptr->details) - FREE_NULL_BITMAP(job_ptr->details->exc_node_bitmap); - } if (job_ptr && (job_ptr->job_id == jobid) && (job_ptr->job_state != JOB_RUNNING)) { @@ -283,22 +268,26 @@ static int _start_job(uint32_t jobid, int task_cnt, char *hostlist, *err_msg = tmp_msg; error("wiki: %s", tmp_msg); - /* Restore remainder of job state. Note the required node - * information is restored above (even if job starts). */ + /* restore some of job state */ job_ptr->priority = 0; job_ptr->num_procs = old_task_cnt; - if (job_ptr->details) { - /* Details get cleared on job abort; happens - * if the request is sufficiently messed up. - * This happens when Moab tries to start a - * a job on invalid nodes (wrong partition). */ - xfree(job_ptr->details->req_nodes); - FREE_NULL_BITMAP(job_ptr->details-> - req_node_bitmap); - xfree(job_ptr->details->req_node_layout); - } rc = -1; } + + if (job_ptr && (job_ptr->job_id == jobid) && job_ptr->details) { + /* Restore required node list in case job requeued */ + xfree(job_ptr->details->req_nodes); + job_ptr->details->req_nodes = save_req_nodes; + FREE_NULL_BITMAP(job_ptr->details->req_node_bitmap); + job_ptr->details->req_node_bitmap = save_req_bitmap; + FREE_NULL_BITMAP(job_ptr->details->exc_node_bitmap); + xfree(job_ptr->details->req_node_layout); + } else { + error("wiki: start_job(%u) job missing", jobid); + xfree(save_req_nodes); + FREE_NULL_BITMAP(save_req_bitmap); + } + unlock_slurmctld(job_write_lock); schedule_node_save(); /* provides own locking */ schedule_job_save(); /* provides own locking */ diff --git a/src/sbatch/opt.c b/src/sbatch/opt.c index cf5f12aa785e0a73d64328997011ea0e47afb7f0..a1ac569a40e85de3fc4c7be20a70e6d4ba3a4873 100644 --- a/src/sbatch/opt.c +++ b/src/sbatch/opt.c @@ -278,7 +278,7 @@ static void _opt_default() opt.ifname = xstrdup("/dev/null"); opt.ofname = NULL; opt.efname = NULL; - opt.get_user_env = false; + opt.get_user_env = -1; } /*---[ env var processing ]-----------------------------------------------*/ @@ -498,7 +498,7 @@ static struct option long_options[] = { {"reboot", no_argument, 0, LONG_OPT_REBOOT}, {"tasks-per-node",required_argument, 0, LONG_OPT_NTASKSPERNODE}, {"wrap", required_argument, 0, LONG_OPT_WRAP}, - {"get-user-env", no_argument, 0, LONG_OPT_GET_USER_ENV}, + {"get-user-env", optional_argument, 0, LONG_OPT_GET_USER_ENV}, {NULL, 0, 0, 0} }; @@ -1205,7 +1205,10 @@ static void _set_options(int argc, char **argv) /* handled in process_options_first_pass() */ break; case LONG_OPT_GET_USER_ENV: - opt.get_user_env = true; + if (optarg) + opt.get_user_env = strtol(optarg, NULL, 10); + else + opt.get_user_env = 0; break; default: fatal("Unrecognized command line parameter %c", diff --git a/src/sbatch/opt.h b/src/sbatch/opt.h index 6d2009f38205a55db66e54ba2a6a4d0ab8731e3c..1c572e5f6e35a3fe4b691fd56aa012f56910be0b 100644 --- a/src/sbatch/opt.h +++ b/src/sbatch/opt.h @@ -133,7 +133,7 @@ typedef struct sbatch_options { char *ifname; /* input file name */ char *ofname; /* output file name */ char *efname; /* error file name */ - bool get_user_env; /* --get-user-env */ + int get_user_env; /* --get-user-env[=timeout] */ } opt_t; extern opt_t opt; diff --git a/src/sbatch/sbatch.c b/src/sbatch/sbatch.c index c0fe4f113ef96145df6fbe819862ad8580954587..f608b538739f6f5d255fc16967960cc15fe88ed1 100644 --- a/src/sbatch/sbatch.c +++ b/src/sbatch/sbatch.c @@ -217,11 +217,12 @@ static int fill_job_desc_from_opts(job_desc_msg_t *desc) desc->shared = opt.shared; desc->environment = NULL; - if (opt.get_user_env) { + if (opt.get_user_env >= 0) { struct passwd *pw = NULL; pw = getpwuid(opt.uid); if (pw != NULL) { - desc->environment = env_array_user_default(pw->pw_name); + desc->environment = env_array_user_default(pw->pw_name, + opt.get_user_env); /* FIXME - should we abort if j->environment * is NULL? */ } diff --git a/src/slurmd/slurmstepd/multi_prog.c b/src/slurmd/slurmstepd/multi_prog.c index 87e0861490eba5bfb4abfc541d1540d59b76ad34..6a1c2e8fd2efcb9e264582b133a05fef160947b3 100644 --- a/src/slurmd/slurmstepd/multi_prog.c +++ b/src/slurmd/slurmstepd/multi_prog.c @@ -151,13 +151,15 @@ multi_prog_get_argv(char *file_contents, char **prog_env, int task_rank, char **prog_argv = NULL; char *local_data = NULL; + prog_argv = (char **)xmalloc(sizeof(char *) * 128); + if (task_rank < 0) { - *argc = 0; - *argv = NULL; + error("Invalid task rank %d", task_rank); + *argc = 1; + *argv = prog_argv; return -1; } - prog_argv = (char **)xmalloc(sizeof(char *) * 128); local_data = xstrdup(file_contents); line = strtok_r(local_data, "\n", &ptrptr); @@ -165,7 +167,7 @@ multi_prog_get_argv(char *file_contents, char **prog_env, int task_rank, if (line_num > 0) line = strtok_r(NULL, "\n", &ptrptr); if (line == NULL) { - error("Could not identify executable program for this task"); + error("No executable program specified for this task"); goto fail; } line_num ++; @@ -272,9 +274,9 @@ multi_prog_get_argv(char *file_contents, char **prog_env, int task_rank, error("Program for task rank %d not specified.", task_rank); fail: - xfree(prog_argv); xfree(local_data); - *argc = 0; - *argv = NULL; + *argc = 1; + prog_argv[0] = NULL; + *argv = prog_argv; return -1; } diff --git a/src/slurmd/slurmstepd/task.c b/src/slurmd/slurmstepd/task.c index 2d10bb2a62c3da974fd058efca9475afb50e3fa6..94c021a3e729a136f81bb20c80893cd851c48c50 100644 --- a/src/slurmd/slurmstepd/task.c +++ b/src/slurmd/slurmstepd/task.c @@ -354,7 +354,7 @@ exec_task(slurmd_job_t *job, int i, int waitfd) job->envtp->env = NULL; xfree(job->envtp->task_count); - if (job->multi_prog) { + if (job->multi_prog && task->argv[0]) { /* * Normally the client (srun/slauch) expands the command name * to a fully qualified path, but in --multi-prog mode it @@ -416,6 +416,10 @@ exec_task(slurmd_job_t *job, int i, int waitfd) job->env[0] = (char *)NULL; } + if (task->argv[0] == NULL) { + error("No executable program specified for this task"); + exit(2); + } execve(task->argv[0], task->argv, job->env); /* diff --git a/src/srun/multi_prog.c b/src/srun/multi_prog.c index 0ed471ccfddd245c6869d9cba5c308278d0b38a1..334c8bdb2fe0cc2c47fa8ed7c887d2504f6ffa3e 100644 --- a/src/srun/multi_prog.c +++ b/src/srun/multi_prog.c @@ -54,6 +54,7 @@ #include <sys/types.h> #include <unistd.h> +#include "src/common/bitstring.h" #include "src/common/log.h" #include "src/common/xassert.h" #include "src/common/xmalloc.h" @@ -132,7 +133,7 @@ _set_exec_names(char *ranks, char *exec_name, int ntasks) if (ranks[0] == '*' && ranks[1] == '\0') { low_num = 0; - high_num = ntasks -1; + high_num = ntasks - 1; _set_range(low_num, high_num, exec_name); return; } @@ -161,7 +162,8 @@ _set_exec_names(char *ranks, char *exec_name, int ntasks) high_num = MIN((ntasks-1), atoi(upper)); _set_range(low_num, high_num, exec_path); } else { - error ("Invalid task range specification (%s) ignored.", range); + error ("Invalid task range specification (%s) ignored.", + range); } } } @@ -188,8 +190,8 @@ mpir_set_multi_name(int ntasks, const char *config_fname) while (fgets(line, sizeof(line), config_fd)) { line_num ++; if (strlen (line) >= (sizeof(line) - 1)) { - error ("Line %d of configuration file too long", - line_num); + error ("Line %d of configuration file %s too long", + line_num, config_fname); fclose(config_fd); return -1; } @@ -206,7 +208,8 @@ mpir_set_multi_name(int ntasks, const char *config_fname) ranks = strtok_r(p, " \t\n", &ptrptr); exec_name = strtok_r(NULL, " \t\n", &ptrptr); if (!ranks || !exec_name) { - error("Line %d is invalid", line_num); + error("Line %d of configuration file %s is invalid", + line_num, config_fname); fclose(config_fd); return -1; } @@ -264,3 +267,150 @@ mpir_dump_proctable() i, tv->host_name, tv->pid, tv->executable_name); } } + +static int +_update_task_mask(int low_num, int high_num, int ntasks, bitstr_t *task_mask) +{ + int i; + + if (low_num > high_num) { + error("Invalid task range, %d-%d", low_num, high_num); + return -1; + } + if (low_num < 0) { + error("Invalid task id, %d < 0", low_num); + return -1; + } + if (high_num >= ntasks) { + error("Invalid task id, %d >= ntasks", high_num); + return -1; + } + for (i=low_num; i<=high_num; i++) { + if (bit_test(task_mask, i)) { + error("Duplicate record for task %d", i); + return -1; + } + bit_set(task_mask, i); + } + return 0; +} + +static int +_validate_ranks(char *ranks, int ntasks, bitstr_t *task_mask) +{ + char *range = NULL, *p = NULL; + char *ptrptr = NULL, *upper = NULL; + int low_num, high_num; + + if (ranks[0] == '*' && ranks[1] == '\0') { + low_num = 0; + high_num = ntasks - 1; + return _update_task_mask(low_num, high_num, ntasks, task_mask); + } + + for (range = strtok_r(ranks, ",", &ptrptr); range != NULL; + range = strtok_r(NULL, ",", &ptrptr)) { + p = range; + while (*p != '\0' && isdigit (*p)) + p ++; + + if (*p == '\0') { /* single rank */ + low_num = atoi(range); + high_num = low_num; + } else if (*p == '-') { /* lower-upper */ + upper = ++ p; + while (isdigit (*p)) + p ++; + if (*p != '\0') { + error ("Invalid task range specification"); + return -1; + } + low_num = atoi(range); + high_num = atoi(upper); + } else { + error ("Invalid task range specification (%s)", + range); + return -1; + } + + if (_update_task_mask(low_num, high_num, ntasks, task_mask)) + return -1; + } + return 0; +} + +/* + * Verify that we have a valid executable program specified for each task + * when the --multi-prog option is used. + * + * Return 0 on success, -1 otherwise + */ +extern int +verify_multi_name(char *config_fname, int ntasks) +{ + FILE *config_fd; + char line[256]; + char *ranks, *exec_name, *p, *ptrptr; + int line_num = 0, i, rc = 0; + bitstr_t *task_mask; + + if (ntasks <= 0) { + error("Invalid task count %d", ntasks); + return -1; + } + + config_fd = fopen(config_fname, "r"); + if (config_fd == NULL) { + error("Unable to open configuration file %s", config_fname); + return -1; + } + + task_mask = bit_alloc(ntasks); + while (fgets(line, sizeof(line), config_fd)) { + line_num ++; + if (strlen (line) >= (sizeof(line) - 1)) { + error ("Line %d of configuration file %s too long", + line_num, config_fname); + rc = -1; + goto fini; + } + p = line; + while (*p != '\0' && isspace (*p)) /* remove leading spaces */ + p ++; + + if (*p == '#') /* only whole-line comments handled */ + continue; + + if (*p == '\0') /* blank line ignored */ + continue; + + ranks = strtok_r(p, " \t\n", &ptrptr); + exec_name = strtok_r(NULL, " \t\n", &ptrptr); + if (!ranks || !exec_name) { + error("Line %d of configuration file %s invalid", + line_num, config_fname); + rc = -1; + goto fini; + } + if (_validate_ranks(ranks, ntasks, task_mask)) { + error("Line %d of configuration file %s invalid", + line_num, config_fname); + rc = -1; + goto fini; + } + } + + for (i=0; i<ntasks; i++) { + if (!bit_test(task_mask, i)) { + error("Configuration file %s invalid, " + "no record for task id %d", + config_fname, i); + rc = -1; + goto fini; + } + } + +fini: fclose(config_fd); + bit_free(task_mask); + return rc; +} diff --git a/src/srun/multi_prog.h b/src/srun/multi_prog.h index bdb0c7de1989e5a4b05d3f68a1440f895907451d..d837ed97e92986c51a7aed7b69cffc2427bb5fad 100644 --- a/src/srun/multi_prog.h +++ b/src/srun/multi_prog.h @@ -48,5 +48,13 @@ extern void mpir_cleanup(void); extern void mpir_set_executable_names(const char *executable_name); extern void mpir_dump_proctable(void); +/* + * Verify that we have a valid executable program specified for each task + * when the --multi-prog option is used. + * + * Return 0 on success, -1 otherwise + */ +extern int verify_multi_name(char *config_fname, int ntasks); + #endif diff --git a/src/srun/opt.c b/src/srun/opt.c index e114a3ab87b49b0f4d87bc65d56ec3333b76bf21..7979b5808c498e2b40d2d572a3e32d2823855726 100644 --- a/src/srun/opt.c +++ b/src/srun/opt.c @@ -84,6 +84,7 @@ #include "src/common/optz.h" #include "src/api/pmi_server.h" +#include "src/srun/multi_prog.h" #include "src/srun/opt.h" #include "src/srun/debugger.h" #include "src/common/mpi.h" @@ -697,7 +698,6 @@ static void _opt_default() opt.msg_timeout = 15; } - opt.get_user_env = false; opt.pty = false; } @@ -1009,7 +1009,7 @@ static void set_options(const int argc, char **argv) {"mloader-image", required_argument, 0, LONG_OPT_MLOADER_IMAGE}, {"ramdisk-image", required_argument, 0, LONG_OPT_RAMDISK_IMAGE}, {"reboot", no_argument, 0, LONG_OPT_REBOOT}, - {"get-user-env", no_argument, 0, LONG_OPT_GET_USER_ENV}, + {"get-user-env", optional_argument, 0, LONG_OPT_GET_USER_ENV}, {"pty", no_argument, 0, LONG_OPT_PTY}, {"checkpoint", required_argument, 0, LONG_OPT_CHECKPOINT}, {NULL, 0, 0, 0} @@ -1494,7 +1494,7 @@ static void set_options(const int argc, char **argv) opt.reboot = true; break; case LONG_OPT_GET_USER_ENV: - opt.get_user_env = true; + error("--get-user-env is no longer supported in srun, use sbatch"); break; case LONG_OPT_PTY: #ifdef HAVE_PTY_H @@ -1635,7 +1635,6 @@ static void _opt_args(int argc, char **argv) exit(1); } _load_multi(&opt.argc, opt.argv); - } else if (opt.argc > 0) { char *fullpath; @@ -1645,6 +1644,9 @@ static void _opt_args(int argc, char **argv) opt.argv[0] = fullpath; } } + + if (opt.multi_prog && verify_multi_name(opt.argv[0], opt.nprocs)) + exit(1); } /* diff --git a/src/srun/opt.h b/src/srun/opt.h index bc574bb2c46e2f83f5ebef7d41df0b98a107551b..2e150aaf2e8d77735d6a8e1d4654de13e69d061f 100644 --- a/src/srun/opt.h +++ b/src/srun/opt.h @@ -198,7 +198,6 @@ typedef struct srun_options { uint16_t mail_type; /* --mail-type */ char *mail_user; /* --mail-user */ char *ctrl_comm_ifhn; /* --ctrl-comm-ifhn */ - bool get_user_env; /* --get-user-env */ bool pty; /* --pty */ int argc; /* length of argv array */ char **argv; /* left over on command line */ diff --git a/testsuite/expect/test1.54 b/testsuite/expect/test1.54 index 573422264b63f05102e119f680c1a576078af566..21a153bfb34e04ff38dfb6b6de8d7135d0038195 100755 --- a/testsuite/expect/test1.54 +++ b/testsuite/expect/test1.54 @@ -96,6 +96,8 @@ if {$matches != 4} { } if {$exit_code != 0} { exit $exit_code +} else { + send_user "\nSo far, so good\n\n" } # @@ -146,6 +148,37 @@ if {$matches != 4} { set exit_code 1 } +if {$exit_code != 0} { + exit $exit_code +} else { + send_user "\nSo far, so good\n\n" +} + +# +# Submit a slurm job that asks for more tasks than specified in our +# configuration file +# +set matches 0 +set srun_pid [spawn $srun -N1 -n5 --overcommit -l -t1 --multi-prog ./$file_in] +expect { + -re "Configuration file .* invalid" { + send_user "\nNo worries. This error is expected\n" + incr matches + } + timeout { + send_user "\nFAILURE: srun not responding\n" + slow_kill $srun_pid + set exit_code 1 + } + eof { + wait + } +} +if {$matches != 1} { + send_user "\nFAILURE: did not note lack of a executable for task 5.\n" + set exit_code 1 +} + if {$exit_code == 0} { exec $bin_rm -f $file_in send_user "\nSUCCESS\n" diff --git a/testsuite/expect/test6.7 b/testsuite/expect/test6.7 index c3b363f8e33ec24f20dbd1a437dd54148c121091..61066ed411248a59e176af256c4c2e480ceb645d 100755 --- a/testsuite/expect/test6.7 +++ b/testsuite/expect/test6.7 @@ -75,7 +75,8 @@ if {[wait_for_job $job_id RUNNING] != 0} { cancel_job $job_id exit 1 } -exec $bin_sleep 2 +# Allow time for the step to start +exec $bin_sleep 4 # # Test verbose scancel