Ejemplo n.º 1
0
/* Convert a composite cpu governor enum to its equivalent string
 *
 * Input:  - buf   - buffer to contain string
 *         - bufsz - size of buffer
 *         - gpvs  - composite enum of governors
 */
extern void
cpu_freq_govlist_to_string(char* buf, uint16_t bufsz, uint32_t govs)
{
	char *list = NULL;

	if ((govs & CPU_FREQ_CONSERVATIVE) == CPU_FREQ_CONSERVATIVE) {
		if (list == NULL)
			list = xstrdup("Conservative");
		else {
			xstrcatchar(list,',');
			xstrcat(list,"Conservative");
		}
	}
	if ((govs & CPU_FREQ_PERFORMANCE) == CPU_FREQ_PERFORMANCE) {
		if (list == NULL)
			list = xstrdup("Performance");
		else {
			xstrcatchar(list,',');
			xstrcat(list,"Performance");
		}
	}
	if ((govs & CPU_FREQ_POWERSAVE) == CPU_FREQ_POWERSAVE) {
		if (list == NULL)
			list = xstrdup("PowerSave");
		else {
			xstrcatchar(list,',');
			xstrcat(list,"PowerSave");
		}
	}
	if ((govs & CPU_FREQ_ONDEMAND) == CPU_FREQ_ONDEMAND) {
		if (list == NULL)
			list = xstrdup("OnDemand");
		else {
			xstrcatchar(list,',');
			xstrcat(list,"OnDemand");
		}
	}
	if ((govs & CPU_FREQ_USERSPACE) == CPU_FREQ_USERSPACE) {
		if (list == NULL)
			list = xstrdup("UserSpace");
		else {
			xstrcatchar(list,',');
			xstrcat(list,"UserSpace");
		}
	}
	if (list) {
		if (strlen(list) < bufsz)
			strcpy(buf, list);
		else
			strncpy(buf, list, bufsz-1);

		xfree(list);
	} else {
		strncpy(buf,"No Governors defined", bufsz-1);
	}
}
Ejemplo n.º 2
0
void log_set_fpfx(char *prefix)
{
	slurm_mutex_lock(&log_lock);
	xfree(log->fpfx);
	if (!prefix)
		log->fpfx = xstrdup("");
	else {
		log->fpfx = xstrdup(prefix);
		xstrcatchar(log->fpfx, ' ');
	}
	slurm_mutex_unlock(&log_lock);
}
Ejemplo n.º 3
0
/* Create an IO filename from job parameters and the filename format
 * sent from client. Used by slurmd for prolog errors. */
extern char *fname_create2(batch_job_launch_msg_t *req)
{
	stepd_step_rec_t job;
	char *esc, *name = NULL, *orig = NULL;

	if (req->std_err)
		orig = xstrdup(req->std_err);
	else if (req->std_out)
		orig = xstrdup(req->std_out);
	else
		xstrfmtcat(orig, "slurm-%u.out", req->job_id);
	esc = is_path_escaped(orig);

	/* If format doesn't specify an absolute pathname, use cwd
	 */
	if (orig[0] != '/') {
		xstrcat(name, req->work_dir);
		if (esc) {
			xstrcat(name, esc);
			goto fini;
		}
		if (name[strlen(name)-1] != '/')
			xstrcatchar(name, '/');
	}

	if (esc) {
		/* esc is malloc */
		name = esc;
		goto fini;
	}

	memset(&job, 0, sizeof(stepd_step_rec_t));
	job.array_job_id	= req->array_job_id;
	job.array_task_id	= req->array_task_id;
	job.jobid		= req->job_id;
//	job->nodeid		= TBD;
	job.stepid		= req->step_id;
	job.uid			= req->uid;
	job.user_name		= req->user_name;
	name = _create_batch_fname(name, orig, &job, 0);

fini:
	xfree(orig);
	return name;
}
Ejemplo n.º 4
0
Archivo: fname.c Proyecto: A1ve5/slurm
/* Create an IO filename from job parameters and the filename format
 * sent from client
 */
char *
fname_create(stepd_step_rec_t *job, const char *format, int taskid)
{
	char *name = NULL;
	char *orig = xstrdup(format);
	int id;
	char *esc;

	if (((id = fname_single_task_io (format)) >= 0) && (taskid != id))
		return (xstrdup ("/dev/null"));

	esc = is_path_escaped(orig);

	/* If format doesn't specify an absolute pathname, use cwd
	 */
	if (orig[0] != '/') {
		xstrcat(name, job->cwd);
		if (esc) {
			xstrcat(name, esc);
			goto fini;
		}
		if (name[strlen(name)-1] != '/')
			xstrcatchar(name, '/');
	}

	if (esc) {
		/* esc is malloc */
		name = esc;
		goto fini;
	}

	if (job->batch)
		name = _create_batch_fname(name, orig, job, taskid);
	else
		name = _create_step_fname(name, orig, job, taskid);

fini:
	xfree(orig);
	return name;
}
Ejemplo n.º 5
0
/* return a heap allocated string formed from fmt and ap arglist
 * returned string is allocated with xmalloc, so must free with xfree.
 *
 * args are like printf, with the addition of the following format chars:
 * - %m expands to strerror(errno)
 * - %t expands to strftime("%x %X") [ locally preferred short date/time ]
 * - %T expands to rfc2822 date time  [ "dd, Mon yyyy hh:mm:ss GMT offset" ]
 *
 * simple format specifiers are handled explicitly to avoid calls to
 * vsnprintf and allow dynamic sizing of the message buffer. If a call
 * is made to vsnprintf, however, the message will be limited to 1024 bytes.
 * (inc. newline)
 *
 */
static char *vxstrfmt(const char *fmt, va_list ap)
{
	char        *buf = NULL;
	char        *p   = NULL;
	size_t      len = (size_t) 0;
	char        tmp[LINEBUFSIZE];
	int         unprocessed = 0;
	int         long_long = 0;

	while (*fmt != '\0') {

		if ((p = (char *)strchr(fmt, '%')) == NULL) {
			/* no more format chars */
			xstrcat(buf, fmt);
			break;

		} else {        /* *p == '%' */
			/* take difference from fmt to just before `%' */
			len = (size_t) ((long)(p) - (long)fmt);
			/* append from fmt to p into buf if there's
			 * anythere there
			 */
			if (len > 0)
				xstrncat(buf, fmt, len);

			switch (*(++p)) {
		        case '%':	/* "%%" => "%" */
				xstrcatchar(buf, '%');
				break;

			case 'm':	/* "%m" => strerror(errno) */
				xslurm_strerrorcat(buf);
				break;

			case 't': 	/* "%t" => locally preferred date/time*/
				xstrftimecat(buf, "%x %X");
				break;
			case 'T': 	/* "%T" => "dd, Mon yyyy hh:mm:ss off" */
				xstrftimecat(buf, "%a, %d %b %Y %H:%M:%S %z");
				break;
#if defined USE_USEC_CLOCK
			case 'M':       /* "%M" => "usec"                    */
				snprintf(tmp, sizeof(tmp), "%ld", clock());
				xstrcat(buf, tmp);
				break;
#elif defined USE_RFC5424_TIME
			case 'M': /* "%M" => "yyyy-mm-ddThh:mm:ss(+/-)hh:mm" */
				xrfc5424timecat(buf);
				break;
#elif defined USE_ISO_8601
			case 'M':       /* "%M" => "yyyy-mm-ddThh:mm:ss"     */
				xstrftimecat(buf, "%Y-%m-%dT%T");
				break;
#else
			case 'M':       /* "%M" => "Mon DD hh:mm:ss"         */
				xstrftimecat(buf, "%b %d %T");
				break;
#endif
			case 's':	/* "%s" => append string */
				/* we deal with this case for efficiency */
				if (unprocessed == 0)
					xstrcat(buf, va_arg(ap, char *));
				else
					xstrcat(buf, "%s");
				break;
			case 'f': 	/* "%f" => append double */
				/* again, we only handle this for efficiency */
				if (unprocessed == 0) {
					snprintf(tmp, sizeof(tmp), "%f",
						 va_arg(ap, double));
					xstrcat(buf, tmp);
				} else
					xstrcat(buf, "%f");
				break;
			case 'd':
				if (unprocessed == 0) {
					snprintf(tmp, sizeof(tmp), "%d",
						 va_arg(ap, int));
					xstrcat(buf, tmp);
				} else
Ejemplo n.º 6
0
static int _parse_resv_tres(char *val, resv_desc_msg_t  *resv_msg_ptr,
                            int *free_tres_license, int *free_tres_bb,
                            int *free_tres_corecnt, int *free_tres_nodecnt)
{
    int i, ret, len;
    char *tres_bb = NULL, *tres_license = NULL,
          *tres_corecnt = NULL, *tres_nodecnt = NULL,
           *token, *type = NULL, *saveptr1 = NULL,
                    *value_str = NULL, *name = NULL, *compound = NULL,
                     *tmp = NULL;
    bool discard, first;

    *free_tres_license = 0;
    *free_tres_bb = 0;
    *free_tres_corecnt = 0;
    *free_tres_nodecnt = 0;

    token = strtok_r(val, ",", &saveptr1);
    while (token) {

        compound = strtok_r(token, "=", &value_str);

        if (!value_str || !*value_str) {
            error("TRES component '%s' has an invalid value '%s'",
                  type, token);
            goto error;
        }

        if (strchr(compound, '/')) {
            tmp = xstrdup(compound);
            type = strtok_r(tmp, "/", &name);
        } else
            type = compound;

        if (_is_configured_tres(compound) < 0)
            goto error;

        if (!strcasecmp(type, "license")) {
            if (tres_license && tres_license[0] != '\0')
                xstrcatchar(tres_license, ',');
            xstrfmtcat(tres_license, "%s:%s", name, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
            if (tmp)
                xfree(tmp);

        } else if (strcasecmp(type, "bb") == 0) {
            if (tres_bb && tres_bb[0] != '\0')
                xstrcatchar(tres_bb, ',');
            xstrfmtcat(tres_bb, "%s:%s", name, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
            if (tmp)
                xfree(tmp);

        } else if (strcasecmp(type, "cpu") == 0) {
            first = true;
            discard = false;
            do {
                len = strlen(value_str);
                for (i = 0; i < len; i++) {
                    if (!isdigit(value_str[i])) {
                        if (first) {
                            error("TRES value '%s' "
                                  "is invalid",
                                  value_str);
                            goto error;
                        } else
                            discard = true;
                        break;
                    }
                }
                first = false;
                if (!discard) {
                    if (tres_corecnt && tres_corecnt[0]
                            != '\0')
                        xstrcatchar(tres_corecnt, ',');
                    xstrcat(tres_corecnt, value_str);

                    token = strtok_r(NULL, ",", &saveptr1);
                    value_str = token;
                }
            } while (!discard && token);

        } else if (strcasecmp(type, "node") == 0) {
            if (tres_nodecnt && tres_nodecnt[0] != '\0')
                xstrcatchar(tres_nodecnt, ',');
            xstrcat(tres_nodecnt, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
        } else {
            error("TRES type '%s' not supported with reservations",
                  compound);
            goto error;
        }

    }

    if (tres_corecnt && tres_corecnt[0] != '\0') {
        ret = _parse_resv_core_cnt(resv_msg_ptr, tres_corecnt, true);
        xfree(tres_corecnt);
        if (ret != SLURM_SUCCESS)
            goto error;
        *free_tres_corecnt = 1;
    }

    if (tres_nodecnt && tres_nodecnt[0] != '\0') {
        ret = _parse_resv_node_cnt(resv_msg_ptr, tres_nodecnt, true);
        xfree(tres_nodecnt);
        if (ret != SLURM_SUCCESS)
            goto error;
        *free_tres_nodecnt = 1;
    }

    if (tres_license && tres_license[0] != '\0') {
        resv_msg_ptr->licenses = tres_license;
        *free_tres_license = 1;
    }

    if (tres_bb && tres_bb[0] != '\0') {
        resv_msg_ptr->burst_buffer = tres_bb;
        *free_tres_bb = 1;
    }

    return SLURM_SUCCESS;

error:
    xfree(tres_nodecnt);
    xfree(tres_corecnt);
    exit_code = 1;
    return SLURM_ERROR;
}
Ejemplo n.º 7
0
/*
 * Fill in as much of filename as possible from srun, update
 * filename type to one of the io types ALL, NONE, PER_TASK, ONE
 */
fname_t *
fname_create(srun_job_t *job, char *format)
{
	unsigned int wid     = 0;
	unsigned long int taskid  = 0;
	fname_t *fname = NULL;
	char *p, *q, *name, *tmp_env;
	uint32_t array_job_id  = job->jobid;
	uint32_t array_task_id = NO_VAL;
	char *esc;
	char *end;

	fname = xmalloc(sizeof(*fname));
	fname->type = IO_ALL;
	fname->name = NULL;
	fname->taskid = -1;

	/* Handle special  cases
	 */

	if ((format == NULL)
	    || (strncasecmp(format, "all", (size_t) 3) == 0)
	    || (strncmp(format, "-", (size_t) 1) == 0)       ) {
		 /* "all" explicitly sets IO_ALL and is the default */
		return fname;
	}

	if (strcasecmp(format, "none") == 0) {
		/*
		 * Set type to IO_PER_TASK so that /dev/null is opened
		 *  on every node, which should be more efficient
		 */
		fname->type = IO_PER_TASK;
		fname->name = xstrdup ("/dev/null");
		return fname;
	}

	taskid = strtoul(format, &p, 10);
	if ((*p == '\0') && ((int) taskid < opt.ntasks)) {
		fname->type   = IO_ONE;
		fname->taskid = (uint32_t) taskid;
		/* Set the name string to pass to slurmd
		 *  to the taskid requested, so that tasks with
		 *  no IO can open /dev/null.
		 */
		fname->name   = xstrdup (format);
		return fname;
	}

	/* Check if path has escaped characters
	 * in it and prevent them to be expanded.
	 */
	esc = _is_path_escaped(format);
	if (esc) {
		fname->name = esc;
		return fname;
	}

	name = NULL;
	q = p = format;
	while (*p != '\0') {
		if (*p == '%') {
			if (isdigit(*(++p))) {
				unsigned long in_width = 0;
				xmemcat(name, q, p - 1);
				if ((in_width = strtoul(p, &p, 10)) > MAX_WIDTH)
					wid = MAX_WIDTH;
				else
					wid = in_width;
				q = p - 1;
				if (*p == '\0')
					break;
			}

			switch (*p) {
			 case 'a':  /* '%a' => array task id   */
				tmp_env = getenv("SLURM_ARRAY_TASK_ID");
				if (tmp_env)
					array_task_id = strtoul(tmp_env, &end, 10);
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*u", wid, array_task_id);
				q = ++p;
				break;
			 case 'A':  /* '%A' => array master job id */
				tmp_env = getenv("SLURM_ARRAY_JOB_ID");
				if (tmp_env)
					array_job_id = strtoul(tmp_env, &end, 10);
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*u", wid, array_job_id);
				q = ++p;
				break;

			 case 't':  /* '%t' => taskid         */
			 case 'n':  /* '%n' => nodeid         */
			 case 'N':  /* '%N' => node name      */

				 fname->type = IO_PER_TASK;
				 if (wid)
					 xstrcatchar(name, '%');
				 p++;
				 break;

			 case 'J':  /* '%J' => "jobid.stepid" */
			 case 'j':  /* '%j' => jobid          */

				 xmemcat(name, q, p - 1);
				 xstrfmtcat(name, "%0*d", wid, job->jobid);

				 if ((*p == 'J') && (job->stepid != NO_VAL))
					 xstrfmtcat(name, ".%d", job->stepid);
				 q = ++p;
				 break;

			 case 's':  /* '%s' => stepid         */
				 xmemcat(name, q, p - 1);
				 xstrfmtcat(name, "%0*d", wid, job->stepid);
				 q = ++p;
				 break;

			 case 'u':  /* '%u' => username       */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%s", opt.user);
				q = ++p;
				break;

			 default:
				 break;
			}
			wid = 0;
		} else
			p++;
	}

	if (q != p)
		xmemcat(name, q, p);

	fname->name = name;
	return fname;
}
Ejemplo n.º 8
0
Archivo: fname.c Proyecto: IFCA/slurm
/* Create an IO filename from job parameters and the filename format
 * sent from client
 */
char *
fname_create(slurmd_job_t *job, const char *format, int taskid)
{
	unsigned int wid   = 0;
	char *name = NULL;
	char *orig = xstrdup(format);
	char *p, *q;
	int id;

	if (((id = fname_single_task_io (format)) >= 0) && (taskid != id)) 
			return (xstrdup ("/dev/null"));

	/* If format doesn't specify an absolute pathname,
	 * use cwd
	 */
	if (orig[0] != '/') {
		xstrcat(name, job->cwd);
		if (name[strlen(name)-1] != '/')
			xstrcatchar(name, '/');
	}

	q = p = orig;
	while (*p != '\0') {
		if (*p == '%') {
			if (isdigit(*(++p))) {
				unsigned long in_width = 0;
				xmemcat(name, q, p - 1);
				if ((in_width = strtoul(p, &p, 10)) > MAX_WIDTH)
					wid = MAX_WIDTH;
				else
					wid = (unsigned int)in_width;
				q = p - 1;
				if (*p == '\0')
					break;
			}

			switch (*p) {
			case 'a':  /* '%a' => array task id   */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid,
					   job->array_task_id);
				q = ++p;
				break;
			case 'A':  /* '%A' => array master job id */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid,
					   job->array_job_id);
				q = ++p;
				break;
			case 's':  /* '%s' => step id        */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->stepid);
				q = ++p;
				break;
			case 't':  /* '%t' => taskid         */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, taskid);
				q = ++p;
				break;
			case 'n':  /* '%n' => nodeid         */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->nodeid);
				q = ++p;
				break;
			case 'N':  /* '%N' => node name      */
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%s", conf->hostname);
				q = ++p;
				break;
			case 'J':
			case 'j':
				xmemcat(name, q, p - 1);
				xstrfmtcat(name, "%0*d", wid, job->jobid);

				if ((*p == 'J') && (job->stepid != NO_VAL))
					xstrfmtcat(name, ".%d", job->stepid);
				q = ++p;
				break;

			default:
				break;
			}
			wid = 0;
			
		} else
			p++;
	}

	if (q != p)
		xmemcat(name, q, p);

	xfree(orig);
	return name;
}
Ejemplo n.º 9
0
extern int state_control_parse_resv_tres(char *val,
					 resv_desc_msg_t *resv_msg_ptr,
					 int *free_tres_license,
					 int *free_tres_bb,
					 int *free_tres_corecnt,
					 int *free_tres_nodecnt,
					 char **err_msg)
{
	int i, ret, len;
	char *tres_bb = NULL, *tres_license = NULL,
		*tres_corecnt = NULL, *tres_nodecnt = NULL,
		*token, *type = NULL, *saveptr1 = NULL,
		*value_str = NULL, *name = NULL, *compound = NULL,
		*tmp = NULL;
	bool discard, first;

	*free_tres_license = 0;
	*free_tres_bb = 0;
	*free_tres_corecnt = 0;
	*free_tres_nodecnt = 0;

	token = strtok_r(val, ",", &saveptr1);
	while (token) {

		compound = strtok_r(token, "=", &value_str);

		if (!compound || !value_str || !*value_str) {
			xstrfmtcat(*err_msg, "invalid TRES '%s'", token);
			goto error;
		}

		if (strchr(compound, '/')) {
			tmp = xstrdup(compound);
			type = strtok_r(tmp, "/", &name);
		} else
			type = compound;

		if (state_control_configured_tres(compound) != SLURM_SUCCESS) {
			xstrfmtcat(*err_msg,
				   "couldn't identify configured TRES '%s'",
				   compound);
			goto error;
		}

		if (!xstrcasecmp(type, "license")) {
			if (tres_license && tres_license[0] != '\0')
				xstrcatchar(tres_license, ',');
			xstrfmtcat(tres_license, "%s:%s", name, value_str);
			token = strtok_r(NULL, ",", &saveptr1);

		} else if (xstrcasecmp(type, "bb") == 0) {
			if (tres_bb && tres_bb[0] != '\0')
				xstrcatchar(tres_bb, ',');
			xstrfmtcat(tres_bb, "%s:%s", name, value_str);
			token = strtok_r(NULL, ",", &saveptr1);

		} else if (xstrcasecmp(type, "cpu") == 0) {
			first = true;
			discard = false;
			do {
				len = strlen(value_str);
				for (i = 0; i < len; i++) {
					if (!isdigit(value_str[i])) {
						if (first) {
							xstrfmtcat(*err_msg,
								   "invalid TRES cpu value '%s'",
								   value_str);
							goto error;
						} else
							discard = true;
						break;
					}
				}
				first = false;
				if (!discard) {
					if (tres_corecnt && tres_corecnt[0]
					    != '\0')
						xstrcatchar(tres_corecnt, ',');
					xstrcat(tres_corecnt, value_str);

					token = strtok_r(NULL, ",", &saveptr1);
					value_str = token;
				}
			} while (!discard && token);

		} else if (xstrcasecmp(type, "node") == 0) {
			if (tres_nodecnt && tres_nodecnt[0] != '\0')
				xstrcatchar(tres_nodecnt, ',');
			xstrcat(tres_nodecnt, value_str);
			token = strtok_r(NULL, ",", &saveptr1);
		} else {
			xstrfmtcat(*err_msg, "TRES type '%s' not supported with reservations",
				   compound);
			goto error;
		}

	}

	if (tres_corecnt && tres_corecnt[0] != '\0') {
		/* only have this on a cons_res machine */
		ret = state_control_corecnt_supported();
		if (ret != SLURM_SUCCESS) {
			xstrfmtcat(*err_msg, "CoreCnt or CPUCnt is only supported when SelectType includes select/cons_res or SelectTypeParameters includes OTHER_CONS_RES on a Cray.");
			goto error;
		}
		ret = state_control_parse_resv_corecnt(resv_msg_ptr,
						       tres_corecnt,
						       free_tres_corecnt, true,
						       err_msg);
		xfree(tres_corecnt);
		if (ret != SLURM_SUCCESS)
			goto error;
	}

	if (tres_nodecnt && tres_nodecnt[0] != '\0') {
		ret = parse_resv_nodecnt(resv_msg_ptr, tres_nodecnt,
					 free_tres_nodecnt, true, err_msg);
		xfree(tres_nodecnt);
		if (ret != SLURM_SUCCESS)
			goto error;
	}

	if (tres_license && tres_license[0] != '\0') {
		resv_msg_ptr->licenses = tres_license;
		*free_tres_license = 1;
	}

	if (tres_bb && tres_bb[0] != '\0') {
		resv_msg_ptr->burst_buffer = tres_bb;
		*free_tres_bb = 1;
	}

	xfree(tmp);
	return SLURM_SUCCESS;

error:
	xfree(tmp);
	xfree(tres_nodecnt);
	xfree(tres_corecnt);
	return SLURM_ERROR;
}
Ejemplo n.º 10
0
Archivo: env.c Proyecto: donaghy1/slurm
int setup_env(env_t *env, bool preserve_env)
{
	int rc = SLURM_SUCCESS;
	char *dist = NULL, *lllp_dist = NULL;
	char addrbuf[INET_ADDRSTRLEN];
	uint32_t cluster_flags = slurmdb_setup_cluster_flags();

	if (env == NULL)
		return SLURM_ERROR;

	if (env->task_pid
	  && setenvf(&env->env, "SLURM_TASK_PID", "%d", (int)env->task_pid)) {
		error("Unable to set SLURM_TASK_PID environment variable");
		 rc = SLURM_FAILURE;
	}

	if (!preserve_env && env->ntasks) {
		if(setenvf(&env->env, "SLURM_NTASKS", "%d", env->ntasks)) {
			error("Unable to set SLURM_NTASKS "
			      "environment variable");
			rc = SLURM_FAILURE;
		}
		if(setenvf(&env->env, "SLURM_NPROCS", "%d", env->ntasks)) {
			error("Unable to set SLURM_NPROCS "
			      "environment variable");
			rc = SLURM_FAILURE;
		}
	}

	if (env->cpus_per_task
	   && setenvf(&env->env, "SLURM_CPUS_PER_TASK", "%d",
		      env->cpus_per_task) ) {
		error("Unable to set SLURM_CPUS_PER_TASK");
		rc = SLURM_FAILURE;
	}

	if (env->ntasks_per_node
	   && setenvf(&env->env, "SLURM_NTASKS_PER_NODE", "%d",
		      env->ntasks_per_node) ) {
		error("Unable to set SLURM_NTASKS_PER_NODE");
		rc = SLURM_FAILURE;
	}

	if (env->ntasks_per_socket
	   && setenvf(&env->env, "SLURM_NTASKS_PER_SOCKET", "%d",
		      env->ntasks_per_socket) ) {
		error("Unable to set SLURM_NTASKS_PER_SOCKET");
		rc = SLURM_FAILURE;
	}

	if (env->ntasks_per_core
	   && setenvf(&env->env, "SLURM_NTASKS_PER_CORE", "%d",
		      env->ntasks_per_core) ) {
		error("Unable to set SLURM_NTASKS_PER_CORE");
		rc = SLURM_FAILURE;
	}

	if (env->cpus_on_node
	   && setenvf(&env->env, "SLURM_CPUS_ON_NODE", "%d",
		      env->cpus_on_node) ) {
		error("Unable to set SLURM_CPUS_ON_NODE");
		rc = SLURM_FAILURE;
	}

	_set_distribution(env->distribution, &dist, &lllp_dist);
	if(dist)
		if (setenvf(&env->env, "SLURM_DISTRIBUTION", "%s", dist)) {
			error("Can't set SLURM_DISTRIBUTION env variable");
			rc = SLURM_FAILURE;
		}

	if(env->distribution == SLURM_DIST_PLANE)
		if (setenvf(&env->env, "SLURM_DIST_PLANESIZE", "%u",
			    env->plane_size)) {
			error("Can't set SLURM_DIST_PLANESIZE "
			      "env variable");
			rc = SLURM_FAILURE;
		}

	if(lllp_dist)
		if (setenvf(&env->env, "SLURM_DIST_LLLP", "%s", lllp_dist)) {
			error("Can't set SLURM_DIST_LLLP env variable");
			rc = SLURM_FAILURE;
		}


	if (env->cpu_bind_type) {
		char *str_verbose, *str_bind_type, *str_bind_list;
		char *str_bind;
		int len;

		if (env->batch_flag) {
			unsetenvp(env->env, "SBATCH_CPU_BIND_VERBOSE");
			unsetenvp(env->env, "SBATCH_CPU_BIND_TYPE");
			unsetenvp(env->env, "SBATCH_CPU_BIND_LIST");
			unsetenvp(env->env, "SBATCH_CPU_BIND");
		} else {
			unsetenvp(env->env, "SLURM_CPU_BIND_VERBOSE");
			unsetenvp(env->env, "SLURM_CPU_BIND_TYPE");
			unsetenvp(env->env, "SLURM_CPU_BIND_LIST");
			unsetenvp(env->env, "SLURM_CPU_BIND");
		}

		str_verbose = xstrdup ("");
		if (env->cpu_bind_type & CPU_BIND_VERBOSE) {
			xstrcat(str_verbose, "verbose");
		} else {
			xstrcat(str_verbose, "quiet");
		}
		str_bind_type = xstrdup ("");
		if (env->cpu_bind_type & CPU_BIND_TO_THREADS) {
			xstrcat(str_bind_type, "threads,");
		} else if (env->cpu_bind_type & CPU_BIND_TO_CORES) {
			xstrcat(str_bind_type, "cores,");
		} else if (env->cpu_bind_type & CPU_BIND_TO_SOCKETS) {
			xstrcat(str_bind_type, "sockets,");
		} else if (env->cpu_bind_type & CPU_BIND_TO_LDOMS) {
			xstrcat(str_bind_type, "ldoms,");
		}
		if (env->cpu_bind_type & CPU_BIND_NONE) {
			xstrcat(str_bind_type, "none");
		} else if (env->cpu_bind_type & CPU_BIND_RANK) {
			xstrcat(str_bind_type, "rank");
		} else if (env->cpu_bind_type & CPU_BIND_MAP) {
			xstrcat(str_bind_type, "map_cpu:");
		} else if (env->cpu_bind_type & CPU_BIND_MASK) {
			xstrcat(str_bind_type, "mask_cpu:");
		} else if (env->cpu_bind_type & CPU_BIND_LDRANK) {
			xstrcat(str_bind_type, "rank_ldom");
		} else if (env->cpu_bind_type & CPU_BIND_LDMAP) {
			xstrcat(str_bind_type, "map_ldom:");
		} else if (env->cpu_bind_type & CPU_BIND_LDMASK) {
			xstrcat(str_bind_type, "mask_ldom:");
		}
		len = strlen(str_bind_type);
		if (len) {		/* remove a possible trailing ',' */
		    	if (str_bind_type[len-1] == ',') {
			    	str_bind_type[len-1] = '\0';
			}
		}
		str_bind_list = xstrdup ("");
		if (env->cpu_bind) {
			xstrcat(str_bind_list, env->cpu_bind);
		}
		str_bind = xstrdup ("");
		xstrcat(str_bind, str_verbose);
		if (str_bind[0] && str_bind_type && str_bind_type[0])
			xstrcatchar(str_bind, ',');
		xstrcat(str_bind, str_bind_type);
		xstrcat(str_bind, str_bind_list);

		if (env->batch_flag) {
			if (setenvf(&env->env, "SBATCH_CPU_BIND_VERBOSE",
				    str_verbose)) {
				error("Unable to set SBATCH_CPU_BIND_VERBOSE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_CPU_BIND_TYPE",
				    str_bind_type)) {
				error("Unable to set SBATCH_CPU_BIND_TYPE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_CPU_BIND_LIST",
				    str_bind_list)) {
				error("Unable to set SBATCH_CPU_BIND_LIST");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_CPU_BIND", str_bind)) {
				error("Unable to set SBATCH_CPU_BIND");
				rc = SLURM_FAILURE;
			}
		} else {
			if (setenvf(&env->env, "SLURM_CPU_BIND_VERBOSE",
				    str_verbose)) {
				error("Unable to set SLURM_CPU_BIND_VERBOSE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_CPU_BIND_TYPE",
				    str_bind_type)) {
				error("Unable to set SLURM_CPU_BIND_TYPE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_CPU_BIND_LIST",
				    str_bind_list)) {
				error("Unable to set SLURM_CPU_BIND_LIST");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_CPU_BIND", str_bind)) {
				error("Unable to set SLURM_CPU_BIND");
				rc = SLURM_FAILURE;
			}
		}
	}

	if (env->mem_bind_type) {
		char *str_verbose, *str_bind_type, *str_bind_list;
		char *str_bind;

		if (env->batch_flag) {
			unsetenvp(env->env, "SBATCH_MEM_BIND_VERBOSE");
			unsetenvp(env->env, "SBATCH_MEM_BIND_TYPE");
			unsetenvp(env->env, "SBATCH_MEM_BIND_LIST");
			unsetenvp(env->env, "SBATCH_MEM_BIND");
		} else {
			unsetenvp(env->env, "SLURM_MEM_BIND_VERBOSE");
			unsetenvp(env->env, "SLURM_MEM_BIND_TYPE");
			unsetenvp(env->env, "SLURM_MEM_BIND_LIST");
			unsetenvp(env->env, "SLURM_MEM_BIND");
		}

		str_verbose = xstrdup ("");
		if (env->mem_bind_type & MEM_BIND_VERBOSE) {
			xstrcat(str_verbose, "verbose");
		} else {
			xstrcat(str_verbose, "quiet");
		}
		str_bind_type = xstrdup ("");
		if (env->mem_bind_type & MEM_BIND_NONE) {
			xstrcat(str_bind_type, "none");
		} else if (env->mem_bind_type & MEM_BIND_RANK) {
			xstrcat(str_bind_type, "rank");
		} else if (env->mem_bind_type & MEM_BIND_MAP) {
			xstrcat(str_bind_type, "map_mem:");
		} else if (env->mem_bind_type & MEM_BIND_MASK) {
			xstrcat(str_bind_type, "mask_mem:");
		} else if (env->mem_bind_type & MEM_BIND_LOCAL) {
			xstrcat(str_bind_type, "local");
		}
		str_bind_list = xstrdup ("");
		if (env->mem_bind) {
			xstrcat(str_bind_list, env->mem_bind);
		}
		str_bind = xstrdup ("");
		xstrcat(str_bind, str_verbose);
		if (str_bind[0]) {		/* add ',' if str_verbose */
			xstrcatchar(str_bind, ',');
		}
		xstrcat(str_bind, str_bind_type);
		xstrcat(str_bind, str_bind_list);

		if (env->batch_flag) {
			if (setenvf(&env->env, "SBATCH_MEM_BIND_VERBOSE",
				    str_verbose)) {
				error("Unable to set SBATCH_MEM_BIND_VERBOSE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_MEM_BIND_TYPE",
				    str_bind_type)) {
				error("Unable to set SBATCH_MEM_BIND_TYPE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_MEM_BIND_LIST",
				    str_bind_list)) {
				error("Unable to set SBATCH_MEM_BIND_LIST");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SBATCH_MEM_BIND", str_bind)) {
				error("Unable to set SBATCH_MEM_BIND");
				rc = SLURM_FAILURE;
			}
		} else {
			if (setenvf(&env->env, "SLURM_MEM_BIND_VERBOSE",
				    str_verbose)) {
				error("Unable to set SLURM_MEM_BIND_VERBOSE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_MEM_BIND_TYPE",
				    str_bind_type)) {
				error("Unable to set SLURM_MEM_BIND_TYPE");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_MEM_BIND_LIST",
				    str_bind_list)) {
				error("Unable to set SLURM_MEM_BIND_LIST");
				rc = SLURM_FAILURE;
			}
			if (setenvf(&env->env, "SLURM_MEM_BIND", str_bind)) {
				error("Unable to set SLURM_MEM_BIND");
				rc = SLURM_FAILURE;
			}
		}
	}

	if (env->overcommit
	    && (setenvf(&env->env, "SLURM_OVERCOMMIT", "1"))) {
		error("Unable to set SLURM_OVERCOMMIT environment variable");
		rc = SLURM_FAILURE;
	}

	if (env->slurmd_debug
	    && setenvf(&env->env, "SLURMD_DEBUG", "%d", env->slurmd_debug)) {
		error("Can't set SLURMD_DEBUG environment variable");
		rc = SLURM_FAILURE;
	}

	if (env->labelio
	   && setenvf(&env->env, "SLURM_LABELIO", "1")) {
		error("Unable to set SLURM_LABELIO environment variable");
		rc = SLURM_FAILURE;
	}

	if (env->select_jobinfo) {
		_setup_particulars(cluster_flags, &env->env,
				   env->select_jobinfo);
	}

	if (env->jobid >= 0) {
		if (setenvf(&env->env, "SLURM_JOB_ID", "%d", env->jobid)) {
			error("Unable to set SLURM_JOB_ID environment");
			rc = SLURM_FAILURE;
		}
		/* and for backwards compatability... */
		if (setenvf(&env->env, "SLURM_JOBID", "%d", env->jobid)) {
			error("Unable to set SLURM_JOBID environment");
			rc = SLURM_FAILURE;
		}
	}

	if (env->nodeid >= 0
	    && setenvf(&env->env, "SLURM_NODEID", "%d", env->nodeid)) {
		error("Unable to set SLURM_NODEID environment");
		rc = SLURM_FAILURE;
	}

	if (env->procid >= 0
	    && setenvf(&env->env, "SLURM_PROCID", "%d", env->procid)) {
		error("Unable to set SLURM_PROCID environment");
		rc = SLURM_FAILURE;
	}

	if (env->localid >= 0
	    && setenvf(&env->env, "SLURM_LOCALID", "%d", env->localid)) {
		error("Unable to set SLURM_LOCALID environment");
		rc = SLURM_FAILURE;
	}

	if (env->stepid >= 0
	    && setenvf(&env->env, "SLURM_STEPID", "%d", env->stepid)) {
		error("Unable to set SLURM_STEPID environment");
		rc = SLURM_FAILURE;
	}

	if (!preserve_env && env->nhosts
	    && setenvf(&env->env, "SLURM_NNODES", "%d", env->nhosts)) {
		error("Unable to set SLURM_NNODES environment var");
		rc = SLURM_FAILURE;
	}

	if (env->nodelist
	    && setenvf(&env->env, "SLURM_NODELIST", "%s", env->nodelist)) {
		error("Unable to set SLURM_NODELIST environment var.");
		rc = SLURM_FAILURE;
	}

	if (!preserve_env && env->task_count
	    && setenvf (&env->env,
			"SLURM_TASKS_PER_NODE", "%s", env->task_count)) {
		error ("Can't set SLURM_TASKS_PER_NODE env variable");
		rc = SLURM_FAILURE;
	}

	if (env->comm_port
	    && setenvf (&env->env, "SLURM_SRUN_COMM_PORT", "%u",
			env->comm_port)) {
		error ("Can't set SLURM_SRUN_COMM_PORT env variable");
		rc = SLURM_FAILURE;
	}

	if (env->cli) {

		slurm_print_slurm_addr (env->cli, addrbuf, INET_ADDRSTRLEN);

		/*
		 *  XXX: Eventually, need a function for slurm_addrs that
		 *   returns just the IP address (not addr:port)
		 */

		if ((dist = strchr (addrbuf, ':')) != NULL)
			*dist = '\0';
		setenvf (&env->env, "SLURM_LAUNCH_NODE_IPADDR", "%s", addrbuf);
	}

	if (env->sgtids
	   && setenvf(&env->env, "SLURM_GTIDS", "%s", env->sgtids)) {
		error("Unable to set SLURM_GTIDS environment variable");
		rc = SLURM_FAILURE;
	}

	if(cluster_flags & CLUSTER_FLAG_AIX) {
		char res_env[128];
		char *debug_env = (char *)getenv("SLURM_LL_API_DEBUG");
		int  debug_num = 0;

		/* MP_POERESTART_ENV causes a warning message for "poe", but
		 * is needed for "poerestart". Presently we have no means to
		 * determine what command a user will execute. We could
		 * possibly add a "srestart" command which would set
		 * MP_POERESTART_ENV, but that presently seems unnecessary. */
		/* setenvf(&env->env, "MP_POERESTART_ENV", res_env); */
		if (debug_env)
			debug_num = atoi(debug_env);
		snprintf(res_env, sizeof(res_env), "SLURM_LL_API_DEBUG=%d",
			debug_num);

		/* Required for AIX/POE systems indicating pre-allocation */
		setenvf(&env->env, "LOADLBATCH", "yes");
		setenvf(&env->env, "LOADL_ACTIVE", "3.2.0");
	}

	if (env->pty_port
	&&  setenvf(&env->env, "SLURM_PTY_PORT", "%hu", env->pty_port)) {
		error("Can't set SLURM_PTY_PORT env variable");
		rc = SLURM_FAILURE;
	}
	if (env->ws_col
	&&  setenvf(&env->env, "SLURM_PTY_WIN_COL", "%hu", env->ws_col)) {
		error("Can't set SLURM_PTY_WIN_COL env variable");
		rc = SLURM_FAILURE;
	}
	if (env->ws_row
	&&  setenvf(&env->env, "SLURM_PTY_WIN_ROW", "%hu", env->ws_row)) {
		error("Can't set SLURM_PTY_WIN_ROW env variable");
		rc = SLURM_FAILURE;
	}
	if (env->ckpt_dir
	&& setenvf(&env->env, "SLURM_CHECKPOINT_IMAGE_DIR", "%s",
		   env->ckpt_dir)) {
		error("Can't set SLURM_CHECKPOINT_IMAGE_DIR env variable");
		rc = SLURM_FAILURE;
	}

	if (env->restart_cnt &&
	    setenvf(&env->env, "SLURM_RESTART_COUNT", "%u", env->restart_cnt)) {
		error("Can't set SLURM_RESTART_COUNT env variable");
		rc = SLURM_FAILURE;
	}

	return rc;
}
Ejemplo n.º 11
0
/*
 * FIXME - It would be nice to parse the multi-prog array just once
 *	to retrieve the argv arrays for each task on this node, rather
 *	than calling multi_prog_get_argv once for each task.
 */
extern int multi_prog_get_argv(char *config_data, char **prog_env,
			       int task_rank, uint32_t *argc, char ***argv,
			       int global_argc, char **global_argv)
{
	char *line = NULL;
	int i, line_num = 0;
	int task_offset;
	char *p = NULL, *ptrptr = NULL;
	char *rank_spec = NULL, *args_spec = NULL;
	int prog_argc = 0;
	char **prog_argv = NULL;
	char *local_data = NULL;
	size_t tmp_buf_len = 256;
	char tmp_buf[tmp_buf_len];
	char *arg_buf = NULL;
	bool last_line_break = false, line_break = false;
	int line_len;


	prog_argv = (char **)xmalloc(sizeof(char *) * MAX_ARGC);

	if (task_rank < 0) {
		error("Invalid task rank %d", task_rank);
		*argc = 1;
		*argv = prog_argv;
		return -1;
	}

	local_data = xstrdup(config_data);
	line = strtok_r(local_data, "\n", &ptrptr);
	while (line) {
		if (line_num > 0)
			line = strtok_r(NULL, "\n", &ptrptr);
		if (line == NULL) {
			error("No executable program specified for this task");
			goto fail;
		}
		line_num++;
		line_len = strlen(line);
		if ((line_len > 0) && (line[line_len - 1] == '\\'))
			line_break = true;
		else
			line_break = false;
		if (last_line_break) {
			last_line_break = line_break;
			continue;
		}
		last_line_break = line_break;
		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;

		rank_spec = p;

		while ((*p != '\0') && !isspace (*p))
			p++;
		if (*p == '\0') {
			error("Invalid MPMD configuration line %d", line_num);
			goto fail;
		}
		*p++ = '\0';

		if (!_in_range(task_rank, rank_spec, &task_offset))
			continue;

		/* skip all whitspace after the range spec */
		while ((*p != '\0') && isspace (*p))
			p++;

		args_spec = p;
		while (*args_spec != '\0') {
			/* Only simple quote and escape supported */
			if (arg_buf) {
				prog_argv[prog_argc++] = arg_buf;
				arg_buf=NULL;
			}
			if ((prog_argc + 1) >= MAX_ARGC) {
				info("Exceeded multi-prog argc limit");
				break;
			}
		CONT:	p = args_spec;
			while ((*args_spec != '\0') && (*args_spec != '\\') &&
			       (*args_spec != '%')  && (*args_spec != '\'') &&
			       !isspace(*args_spec)) {
				args_spec++;
			}
			xstrncat(arg_buf, p, (args_spec - p));
			if (*args_spec == '\0') {
				/* the last argument */
				break;

			} else if (*args_spec == '%') {
				args_spec++;
				if (*args_spec == 't') {
					/* task rank */
					snprintf(tmp_buf, tmp_buf_len, "%d",
						 task_rank);
					xstrcat(arg_buf, tmp_buf);
				} else if (*args_spec == 'o') {
					/* task offset */
					snprintf(tmp_buf, tmp_buf_len, "%d",
						 task_offset);
					xstrcat(arg_buf, tmp_buf);
				}
				args_spec++;
				goto CONT;

			} else if (*args_spec == '\\') {
				/* escape, just remove the backslash */
				args_spec++;
				if (*args_spec != '\0') {
					xstrcatchar(arg_buf, *args_spec);
					args_spec++;
				} else {
					line = strtok_r(NULL, "\n", &ptrptr);
					if (!line)
						break;
					line_num++;
					args_spec = line;
				}
				goto CONT;

			} else if (*args_spec == '\'') {
				/* single quote,
				 * preserve all characters quoted. */
				p = ++args_spec;
		LINE_BREAK:	while ((*args_spec != '\0') &&
				       (*args_spec != '\'')) {
					args_spec++;
				}
				if (*args_spec == '\0') {
					/* closing quote not found */
					if (*(args_spec - 1) == '\\') {
						line = strtok_r(NULL, "\n",
								&ptrptr);
						if (line) {
							line_num++;
							args_spec = line;
							goto LINE_BREAK;
						}
					}
					error("Program arguments specification format invalid: %s.",
					      prog_argv[prog_argc - 1]);
					goto fail;
				}
				xstrncat(arg_buf, p, (args_spec - p));
				args_spec++;
				goto CONT;

			} else {
				/* space */
				while ((*args_spec != '\0') &&
				       isspace(*args_spec)) {
					args_spec++;
				}
			}

		}
		if (arg_buf) {
			prog_argv[prog_argc++] = arg_buf;
			arg_buf = NULL;
		}

		for (i = 2; i < global_argc; i++) {
			if ((prog_argc + 1) >= MAX_ARGC) {
				info("Exceeded multi-prog argc limit");
				break;
			}
			prog_argv[prog_argc++] = xstrdup(global_argv[i]);
		}
		prog_argv[prog_argc] = NULL;

		*argc = prog_argc;
		*argv = prog_argv;
		xfree(local_data);
		return 0;
	}

	error("Program for task rank %d not specified.", task_rank);
fail:
	xfree(local_data);
	*argc = 1;
	prog_argv[0] = NULL;
	*argv = prog_argv;
	return -1;
}