int drmaa_get_vector_attribute( drmaa_job_template_t *jt, const char *name, drmaa_attr_values_t **out_values, char *errmsg, size_t errlen ) { const drmaa_attrib_info_t *attr; unsigned i, n_values; char **v, **value; attr = attr_by_drmaa_name(name); if (attr == NULL || !drmaa_is_vector(attr)) RAISE_DRMAA(DRMAA_ERRNO_INVALID_ARGUMENT); pthread_mutex_lock(&jt->mutex); value = (char**)jt->attrib[ attr->code ]; pthread_mutex_unlock(&jt->mutex); if (value == NULL) { *out_values = NULL; return DRMAA_ERRNO_SUCCESS; } for (n_values = 0; value[n_values] != NULL; n_values++) {} v = (char**)calloc(n_values + 1, sizeof(char*)); if (v == NULL) RAISE_NO_MEMORY(); for (i = 0; i < n_values; i++) { v[i] = strdup(value[i]); if (v[i] == NULL) { drmaa_free_vector(v); RAISE_NO_MEMORY(); } } v[n_values] = NULL; *out_values = malloc(sizeof(drmaa_attr_values_t)); (*out_values)->list = (*out_values)->iter = v; return DRMAA_ERRNO_SUCCESS; }
int drmaa_set_vector_attribute( drmaa_job_template_t *jt, const char *name, const char *value[], char *errmsg, size_t errlen ) { const drmaa_attrib_info_t *attr; char **v; int attr_no; unsigned i, n_values; attr = attr_by_drmaa_name(name); if (attr == NULL || !drmaa_is_vector(attr)) RAISE_DRMAA(DRMAA_ERRNO_INVALID_ARGUMENT); attr_no = attr->code; for (n_values = 0; value[n_values] != NULL; n_values++) {} v = (char**)calloc(n_values + 1, sizeof(char*)); if (v == NULL) RAISE_NO_MEMORY(); for (i = 0; i < n_values; i++) { v[i] = strdup(value[i]); if (v[i] == NULL) { drmaa_free_vector(v); RAISE_NO_MEMORY(); } } v[n_values] = NULL; pthread_mutex_lock(&jt->mutex); if (jt->attrib[attr_no] != NULL) drmaa_free_vector((char**)jt->attrib[attr_no]); jt->attrib[attr_no] = v; pthread_mutex_unlock(&jt->mutex); return DRMAA_ERRNO_SUCCESS; }
int drmaa_create_submission_context( drmaa_submission_context_t **c, const drmaa_job_template_t *jt, int bulk_no, char *errmsg, size_t errlen) { drmaa_submission_context_t *sc; sc = (drmaa_submission_context_t*)malloc(sizeof(drmaa_submission_context_t)); if (sc == NULL) RAISE_NO_MEMORY(); sc->jt = jt; sc->pbs_attribs = NULL; sc->script_filename = NULL; sc->home_directory = strdup(getenv("HOME")); if (jt->attrib[ATTR_JOB_WORKING_DIR] != NULL) sc->working_directory = strdup((const char *)jt->attrib[ATTR_JOB_WORKING_DIR]); else sc->working_directory = strdup(sc->home_directory); asprintf(&sc->bulk_incr_no, "%d", bulk_no); *c = sc; return DRMAA_ERRNO_SUCCESS; }
int drmaa_allocate_job_template(drmaa_job_template_t **p_jt, char *errmsg, size_t errlen) { drmaa_session_t *c = NULL; drmaa_job_template_t *jt = NULL; DEBUG(("-> drmaa_allocate_job_template")); GET_DRMAA_SESSION(c); jt = (drmaa_job_template_t*)malloc(sizeof(drmaa_job_template_t)); if (jt == NULL) { RELEASE_DRMAA_SESSION(c); RAISE_NO_MEMORY(); } jt->session = c; jt->attrib = (void**)calloc(N_DRMAA_ATTRIBS, sizeof(void*)); if (jt->attrib == NULL) { free(jt); RELEASE_DRMAA_SESSION(c); RAISE_NO_MEMORY(); } pthread_mutex_init(&jt->mutex, NULL); pthread_mutex_lock(& c->jobs_mutex); jt->next = c->jt_list->next; jt->prev = c->jt_list; jt->next->prev = jt; jt->prev->next = jt; pthread_mutex_unlock(& c->jobs_mutex); *p_jt = jt; RELEASE_DRMAA_SESSION(c); DEBUG(("<- drmaa_allocate_job_template")); return DRMAA_ERRNO_SUCCESS; }
/** * Writes temporary file. * @param filename Upon successful return temporary * file name will be stored here. * @param content Buffer with content to write. * @param len Buffer's length. * @return DRMAA return code. */ int drmaa_write_tmpfile( char **filename, const char *content, size_t len, char *errmsg, size_t errlen ) { char *name; int fd; #define TMPFILE_TEMPLATE "/tmp/pbs_drmaa.XXXXXX" DEBUG(("-> drmaa_write_tmpfile(content=\"%.*s\")", len, content)); name = strdup(TMPFILE_TEMPLATE); if (name == NULL) RAISE_NO_MEMORY(); fd = mkstemp(name); if (fd < 0) RAISE_ERRNO(DRMAA_ERRNO_INTERNAL_ERROR); while (len > 0) { size_t written = write(fd, content, len); if (written != (size_t) - 1) { content += written; len -= written; } else { free(name); close(fd); RAISE_ERRNO(DRMAA_ERRNO_INTERNAL_ERROR); } } if (close(fd)) { free(name); RAISE_ERRNO(DRMAA_ERRNO_INTERNAL_ERROR); } DEBUG(("<- drmaa_write_tmpfile; filename=%s", name)); *filename = name; return DRMAA_ERRNO_SUCCESS; }
/** * Set e-mail notification about job state. */ int drmaa_set_job_email_notication( drmaa_submission_context_t *c, char *errmsg, size_t errlen ) { void **attrib = c->jt->attrib; const char *block_email = (const char*)attrib[ATTR_BLOCK_EMAIL]; int rc; if (block_email != NULL && !strcmp(block_email, "1")) { rc = drmaa_add_pbs_attr(c, ATTR_MAIL_POINTS, strdup(""), 0, errmsg, errlen); if (rc) return rc; } else { const char **mail_list = (const char**)attrib[ATTR_EMAIL]; char *pbs_mail_list = NULL; if (mail_list != NULL) { pbs_mail_list = drmaa_explode(mail_list, ','); if (pbs_mail_list == NULL) RAISE_NO_MEMORY(); rc = drmaa_add_pbs_attr(c, ATTR_EMAIL, pbs_mail_list, 0, errmsg, errlen); if (rc) { free(pbs_mail_list); return rc; } /* a mail is sent when the job is aborted by the batch system. b mail is sent when the job begins execution. e mail is sent when the job terminates. */ rc = drmaa_add_pbs_attr(c, ATTR_MAIL_POINTS, strdup("ae"), 0, errmsg, errlen); if (rc) return rc; } } return DRMAA_ERRNO_SUCCESS; }
/** * Adds jobs PBS attributes list. * @param attr_code Attribute code (@ref drmaa_attribute_t). * @param value Attribute value -- null terminated string allocated with * malloc(); <b>callee</b> is responsible for freeing it. * @param placeholders Placeholders to substitute inside value. * It have following bits: * - @ref DRMAA_PLACEHOLDER_MASK_HD -- replaces @ref DRMAA_PLACEHOLDER_HD with * user's home direcotry, * - @ref DRMAA_PLACEHOLDER_MASK_WD -- replaces @ref DRMAA_PLACEHOLDER_WD with * job's working direcotry, * - @ref DRMAA_PLACEHOLDER_MASK_INCR -- replaces @ref DRMAA_PLACEHOLDER_INCR * with bulk job index. */ int drmaa_add_pbs_attr( drmaa_submission_context_t *c, int attr_code, char *value, unsigned placeholders, char *errmsg, size_t errlen ) { struct attropl *attr = NULL; value = drmaa_expand_placeholders(c, value, placeholders); if (value == NULL) goto cleanup; attr = (struct attropl*)malloc(sizeof(*attr)); if (attr == NULL) goto cleanup; attr->next = c->pbs_attribs; attr->name = strdup(drmaa_attr_table[attr_code].pbs_name); if (attr->name == NULL) goto cleanup; attr->value = value; attr->resource = NULL; attr->op = SET; c->pbs_attribs = attr; return DRMAA_ERRNO_SUCCESS; cleanup: if (value != NULL) free(value); if (attr != NULL) free(attr); RAISE_NO_MEMORY(); }
/** Sets job environment variables. */ int drmaa_set_job_environment( drmaa_submission_context_t *c, char *errmsg, size_t errlen ) { void **attrib = c->jt->attrib; size_t s; char *env; char *tmp = NULL; int rc; env = strdup(""); s = strlen(env); if (attrib[ATTR_ENV] != NULL) { char *value = drmaa_explode((const char **)attrib[ATTR_ENV], ','); if (value == NULL) { free(env); RAISE_NO_MEMORY(); } tmp = (char *)realloc(env, s + strlen(value) + 1); if (tmp == NULL) { free(env); return DRMAA_ERRNO_NO_MEMORY; } env = tmp; strcpy(env + s, value); free(value); } else env[s-1] = 0; rc = drmaa_add_pbs_attr(c, ATTR_ENV, env, DRMAA_PLACEHOLDER_MASK_INCR, errmsg, errlen); if (rc) return rc; return DRMAA_ERRNO_SUCCESS; }
/** Creates DRMAA session and opens connection with DRM. */ int drmaa_create(drmaa_session_t **pc, const char *contact, char *errmsg, size_t errlen) { drmaa_session_t *c; c = malloc(sizeof(drmaa_session_t)); if (c == NULL) RAISE_NO_MEMORY(); c->pbs_conn = -1; c->contact = NULL; c->jt_list = NULL; c->job_hashtab = NULL; c->next_time_label = 0; pthread_mutex_init(&c->conn_mutex, NULL); pthread_mutex_init(&c->jobs_mutex, NULL); c->jt_list = (drmaa_job_template_t*)malloc(sizeof(drmaa_job_template_t)); if (c->jt_list == NULL) { drmaa_destroy(c, errmsg, errlen); RAISE_NO_MEMORY(); } c->jt_list->next = c->jt_list->prev = c->jt_list; c->job_hashtab = (drmaa_job_t**)calloc(HASHTAB_SIZE, sizeof(drmaa_job_t*)); if (c->job_hashtab == NULL) { drmaa_destroy(c, errmsg, errlen); RAISE_NO_MEMORY(); } c->pbs_conn = pbs_connect((char*)contact); DEBUG(("pbs_connect(%s)=%d", contact, c->pbs_conn)); if (c->pbs_conn < 0) { drmaa_destroy(c, errmsg, errlen); RAISE_PBS(); } if (contact) c->contact = strdup(contact); else c->contact = strdup(pbs_server); if (c->contact == NULL) { drmaa_destroy(c, errmsg, errlen); RAISE_NO_MEMORY(); } *pc = c; return DRMAA_ERRNO_SUCCESS; }
int drmaa_run_bulk_jobs( drmaa_job_ids_t **job_ids, const drmaa_job_template_t *jt, int start, int end, int incr, char *errmsg, size_t errlen ) { unsigned n_jobs; unsigned i; char **j; int rc = DRMAA_ERRNO_SUCCESS; DEBUG(("-> drmaa_run_bulk_jobs(start=%d,end=%d,incr=%d)", start, end, incr)); /* Be conform with general DRMAA specifiaction * -- accept negative incr with end <= start. */ if (incr < 0) { /* swap(start,end) */ int tmp; tmp = start; start = end; end = tmp; incr = - incr; } if (0 < start && start <= end && 0 < incr) {} else return DRMAA_ERRNO_INVALID_ARGUMENT; n_jobs = (end - start) / incr + 1; *job_ids = (drmaa_job_ids_t*)malloc(sizeof(drmaa_job_ids_t)); if (*job_ids == NULL) RAISE_NO_MEMORY(); (*job_ids)->list = (*job_ids)->iter = (char**) calloc(n_jobs + 1, sizeof(char*)); if ((*job_ids)->list == NULL) { free(*job_ids); RAISE_NO_MEMORY(); } j = (*job_ids)->list; for (i = start; i <= (unsigned)end; i += incr) { char *job_id = (char*)malloc(DRMAA_JOBNAME_BUFFER); if (job_id == NULL) { drmaa_release_job_ids(*job_ids); RAISE_NO_MEMORY(); } rc = drmaa_run_job_impl(job_id, DRMAA_JOBNAME_BUFFER, jt, i, errmsg, errlen); *j++ = job_id; if (rc) { drmaa_release_job_ids(*job_ids); return rc; } } *j++ = NULL; DEBUG(("<- drmaa_run_bulk_jobs() =%d, job_ids=%p", rc, (void*)*job_ids)); return DRMAA_ERRNO_SUCCESS; }
/** Writes job's PBS script to temporary file. */ int drmaa_create_job_script( drmaa_submission_context_t *c, char *errmsg, size_t errlen ) { size_t script_size; const char *job, *wd, **argv; char *input_path; char *script, *s; const char **i; int rc; void **attrib = c->jt->attrib; job = (const char*) attrib[ ATTR_JOB_PATH ]; wd = (const char*) attrib[ ATTR_JOB_WORKING_DIR ]; argv = (const char**)attrib[ ATTR_ARGV ]; input_path = (char *) attrib[ ATTR_INPUT_PATH ]; if (job == NULL) RAISE_DRMAA(DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE); /* compute script length */ script_size = 0; if (wd != NULL) script_size += strlen("cd ") + strlen(wd) + strlen("; "); script_size += strlen("exec ") + strlen(job); if (argv != NULL) for (i = argv; *i != NULL; i++) script_size += 1 + strlen(*i); if (input_path != NULL) script_size += sizeof(" <") + strlen(input_path); script = (char*)malloc(script_size + 1); if (script == NULL) RAISE_NO_MEMORY(); s = script; if (wd != NULL) s += sprintf(s, "cd %s; ", wd); s += sprintf(s, "exec %s", job); if (argv != NULL) for (i = argv; *i != NULL; i++) s += sprintf(s, " %s", *i); if (input_path != NULL) { char *colon = strchr(input_path, ':'); if (colon != NULL) input_path = colon + 1; s += sprintf(s, " <%s", input_path); } DEBUG(("script before substitution = {%s}", script)); script = drmaa_expand_placeholders(c, script, DRMAA_PLACEHOLDER_MASK_HD | DRMAA_PLACEHOLDER_MASK_WD | DRMAA_PLACEHOLDER_MASK_INCR); DEBUG(("script after substitution = {%s}", script)); rc = drmaa_write_tmpfile(&c->script_filename, script, strlen(script), errmsg, errlen); free(script); return rc; }