/* * Substitute the path option for a batch job * */ static void _batch_path_check(char **p, char **q, char **name, unsigned int wid, stepd_step_rec_t *job, int taskid) { switch (**p) { case 'a': /* '%a' => array task id */ xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%0*u", wid, job->array_task_id); *q = ++(*p); break; case 'A': /* '%A' => array master job id */ xmemcat(*name, *q, *p - 1); if (job->array_task_id == NO_VAL) xstrfmtcat(*name, "%0*u", wid, job->jobid); else xstrfmtcat(*name, "%0*u",wid, job->array_job_id); *q = ++(*p); break; case 'J': /* '%J' => jobid.stepid */ case 'j': /* '%j' => jobid */ xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%0*u", wid, job->jobid); if ((**p == 'J') && (job->stepid != NO_VAL)) xstrfmtcat(*name, ".%u", job->stepid); *q = ++(*p); break; case 'n': /* '%n' => nodeid */ xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%0*u", 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 's': /* '%s' => step id */ xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%0*u", wid, job->stepid); *q = ++(*p); break; case 't': /* '%t' => taskid */ xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%0*u", wid, taskid); *q = ++(*p); break; case 'u': /* '%u' => user name */ if (!job->user_name) job->user_name = uid_to_string(job->uid); xmemcat(*name, *q, *p - 1); xstrfmtcat(*name, "%s", job->user_name); *q = ++(*p); break; default: break; } }
/* * Substitute the path option for a step. * */ static void _step_path_check(char **p, char **q, char **name, unsigned int wid, bool double_p, stepd_step_rec_t *job, int taskid, int offset) { switch (**p) { case '%': /* This is in case there is a 3rd %, ie. %%% */ xmemcat(*name, *q, *p - 1); *q = *p; break; case 't': /* '%t' => taskid */ xmemcat(*name, *q, *p - offset); if (!double_p) { if (job->pack_task_offset != NO_VAL) taskid += job->pack_task_offset; xstrfmtcat(*name, "%0*u", wid, taskid); (*p)++; } *q = (*p)++; break; case 'n': /* '%n' => nodeid */ xmemcat(*name, *q, *p - offset); if (!double_p) { xstrfmtcat(*name, "%0*u", wid, job->nodeid); (*p)++; } *q = (*p)++; break; case 'N': /* '%N' => node name */ xmemcat(*name, *q, *p - offset); if (!double_p) { xstrfmtcat(*name, "%s", conf->hostname); (*p)++; } *q = (*p)++; break; case 'u': /* '%u' => user name */ if (!job->user_name) job->user_name = uid_to_string(job->uid); xmemcat(*name, *q, *p - 1); if (!double_p) { xstrfmtcat(*name, "%s", job->user_name); (*p)++; } *q = (*p)++; break; default: break; } }
static char *_create_batch_fname(char *name, char *path, stepd_step_rec_t *job, int taskid) { unsigned int wid = 0; char *p, *q; q = p = path; while (*p != '\0') { if (*p == '%') { if (*(p+1) == '%') { p++; xmemcat(name, q, p); q = ++p; continue; } 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; } _batch_path_check(&p, &q, &name, wid, job, taskid); wid = 0; } else p++; } if (q != p) xmemcat(name, q, p); return name; }
static char *_create_step_fname (char *name, char *path, stepd_step_rec_t *job, int taskid) { unsigned int wid = 0; char *p, *q; bool double_p = false; int str_offset = 1; q = p = path; while (*p != '\0') { if (*p == '%') { if (*(p+1) == '%') { p++; double_p = true; } if (isdigit(*(++p))) { unsigned long in_width = 0; if ((in_width = strtoul(p, &p, 10)) == MAX_WIDTH) { /* Remove % and double digit 10 */ str_offset = 3; } else str_offset = 2; wid = (unsigned int)in_width; if (*p == '\0') break; } _step_path_check(&p, &q, &name, wid, double_p, job, taskid, str_offset); wid = 0; } else p++; double_p = false; str_offset = 1; } if (q != p) xmemcat(name, q, p); return name; }
/* * 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; }
/* 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; }