static void _xlate_before(char *depend, uint32_t submit_uid, uint32_t my_job_id) { uint32_t job_id; char *last_ptr = NULL, *new_dep = NULL, *tok, *type; struct job_record *job_ptr; pthread_attr_t attr; pthread_t dep_thread; tok = strtok_r(depend, ":", &last_ptr); if (!xstrcmp(tok, "before")) type = "after"; else if (!xstrcmp(tok, "beforeany")) type = "afterany"; else if (!xstrcmp(tok, "beforenotok")) type = "afternotok"; else if (!xstrcmp(tok, "beforeok")) type = "afterok"; else { info("%s: discarding invalid job dependency option %s", plugin_type, tok); return; } /* NOTE: We are updating a job record here in order to implement * the depend=before option. We are doing so without the write lock * on the job record, but using a local mutex to prevent multiple * updates on the same job when multiple jobs satisfying the dependency * are being processed at the same time (all with read locks). The * job read lock will prevent anyone else from getting a job write * lock and using a job write lock causes serious performance problems * for slow job_submit plugins. Not an ideal solution, but the best * option that we see. */ slurm_mutex_lock(&depend_mutex); tok = strtok_r(NULL, ":", &last_ptr); while (tok) { job_id = atoi(tok); job_ptr = find_job_record(job_id); if (!job_ptr) { info("%s: discarding invalid job dependency before %s", plugin_type, tok); } else if ((submit_uid != job_ptr->user_id) && !validate_super_user(submit_uid)) { error("%s: Security violation: uid %u trying to alter " "job %u belonging to uid %u", plugin_type, submit_uid, job_ptr->job_id, job_ptr->user_id); } else if ((!IS_JOB_PENDING(job_ptr)) || (job_ptr->details == NULL)) { info("%s: discarding job before dependency on " "non-pending job %u", plugin_type, job_ptr->job_id); } else { if (job_ptr->details->dependency) { xstrcat(new_dep, job_ptr->details->dependency); xstrcat(new_dep, ","); } xstrfmtcat(new_dep, "%s:%u", type, my_job_id); xfree(job_ptr->details->dependency); job_ptr->details->dependency = new_dep; new_dep = NULL; _decr_depend_cnt(job_ptr); slurm_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&dep_thread, &attr, _dep_agent, job_ptr); slurm_attr_destroy(&attr); } tok = strtok_r(NULL, ":", &last_ptr); } slurm_mutex_unlock(&depend_mutex); }
static void _xlate_before(char *depend, uint32_t submit_uid, uint32_t my_job_id) { uint32_t job_id; char *last_ptr = NULL, *new_dep = NULL, *tok, *type; struct job_record *job_ptr; pthread_attr_t attr; pthread_t dep_thread; tok = strtok_r(depend, ":", &last_ptr); if (!strcmp(tok, "before")) type = "after"; else if (!strcmp(tok, "beforeany")) type = "afterany"; else if (!strcmp(tok, "beforenotok")) type = "afternotok"; else if (!strcmp(tok, "beforeok")) type = "afterok"; else { info("%s: discarding invalid job dependency option %s", plugin_type, tok); return; } tok = strtok_r(NULL, ":", &last_ptr); while (tok) { job_id = atoi(tok); job_ptr = find_job_record(job_id); if (!job_ptr) { info("%s: discarding invalid job dependency before %s", plugin_type, tok); } else if ((submit_uid != job_ptr->user_id) && !validate_super_user(submit_uid)) { error("%s: Security violation: uid %u trying to alter " "job %u belonging to uid %u", plugin_type, submit_uid, job_ptr->job_id, job_ptr->user_id); } else if ((!IS_JOB_PENDING(job_ptr)) || (job_ptr->details == NULL)) { info("%s: discarding job before dependency on " "non-pending job %u", plugin_type, job_ptr->job_id); } else { if (job_ptr->details->dependency) { xstrcat(new_dep, job_ptr->details->dependency); xstrcat(new_dep, ","); } xstrfmtcat(new_dep, "%s:%u", type, my_job_id); xfree(job_ptr->details->dependency); job_ptr->details->dependency = new_dep; new_dep = NULL; _decr_depend_cnt(job_ptr); slurm_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&dep_thread, &attr, _dep_agent, job_ptr); slurm_attr_destroy(&attr); } tok = strtok_r(NULL, ":", &last_ptr); } }