static void fsd_template_set_v_attr( fsd_template_t *self, const char *name, const char **value ) { const fsd_attribute_t *attr = NULL; char **volatile v = NULL; if( name == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); attr = self->by_name( self, name ); if( attr == NULL || ! attr->is_vector ) fsd_exc_raise_fmt( FSD_ERRNO_INVALID_ARGUMENT, "invalid vector attribute name: %s", name ); TRY { int code = attr->code; if( value != NULL ) v = fsd_copy_vector( value ); if( self->attributes[code] != NULL ) fsd_free_vector( self->attributes[code] ); self->attributes[code] = v; v = NULL; } FINALLY { fsd_free_vector( v ); } END_TRY }
fsd_iter_t * fsd_drmaa_session_run_bulk( fsd_drmaa_session_t *self, const fsd_template_t *jt, int start, int end, int incr ) { volatile unsigned n_jobs; char **volatile result = NULL; if( incr > 0 ) n_jobs = (end-start) / incr + 1; else n_jobs = (start-end) / -incr + 1; TRY { unsigned i; int idx; fsd_calloc( result, n_jobs, char* ); for( i=0, idx=start; i < n_jobs; i++, idx+=incr ) result[i] = self->run_impl( self, jt, idx ); } EXCEPT_DEFAULT { if( result ) fsd_free_vector( result ); fsd_exc_reraise(); } END_TRY return fsd_iter_new( result, -1 ); }
void fsd_drmaa_session_control_job( fsd_drmaa_session_t *self, const char *job_id, int action ) { char **job_ids = NULL; char **i; TRY { if( !strcmp( job_id, DRMAA_JOB_IDS_SESSION_ALL ) ) job_ids = self->get_submited_job_ids( self ); else { fsd_calloc( job_ids, 2, char* ); job_ids[0] = fsd_strdup( job_id ); } for( i = job_ids; *i != NULL; i++ ) { fsd_job_t *job = NULL; TRY { job = self->get_job( self, *i ); if( job == NULL ) { if( !strcmp( job_id, DRMAA_JOB_IDS_SESSION_ALL ) ) { /* job was just removed from session */ } else job = self->new_job( self, *i ); } if( job ) job->control( job, action ); } FINALLY { if ( job ) job->release( job ); } END_TRY } } FINALLY { fsd_free_vector( job_ids ); } END_TRY }
static fsd_iter_t * fsd_iter_new_impl( char **list, int length, bool own ) { fsd_iter_t *volatile self = NULL; TRY { fsd_malloc( self, fsd_iter_t ); self->next = fsd_iter_next; self->reset = fsd_iter_reset; self->len = fsd_iter_len; self->append = fsd_iter_append; self->destroy = fsd_iter_destroy; self->_list = list; self->_position = 0; if( list == NULL ) self->_length = 0; else if( length >= 0 ) self->_length = length; else { char **i; int cnt = 0; for( i = self->_list; *i != NULL; i++ ) cnt++; self->_length = cnt; } self->_own_list = own; } EXCEPT_DEFAULT { if( own && list ) { if( length >= 0 ) { int i; for( i = 0; i < length; i++ ) fsd_free( list[i] ); fsd_free( list ); } else fsd_free_vector( list ); } fsd_exc_reraise(); } END_TRY return self; }
void fsd_drmaa_session_synchronize( fsd_drmaa_session_t *self, const char **input_job_ids, const struct timespec *timeout, bool dispose ) { volatile bool wait_for_all = false; char **volatile job_ids_buf = NULL; const char **job_ids = NULL; const char **i; fsd_log_enter(( "(job_ids={...}, timeout=..., dispose=%d)", (int)dispose )); if( input_job_ids == NULL ) fsd_exc_raise_code( FSD_ERRNO_INVALID_ARGUMENT ); TRY { for( i = input_job_ids; *i != NULL; i++ ) if( !strcmp(*i, DRMAA_JOB_IDS_SESSION_ALL) ) wait_for_all = true; if( wait_for_all ) { job_ids_buf = self->get_submited_job_ids( self ); job_ids = (const char**)job_ids_buf; } else job_ids = input_job_ids; for( i = job_ids; *i != NULL; i++ ) TRY { self->wait_for_single_job( self, *i, timeout, NULL, NULL, dispose ); } EXCEPT( FSD_DRMAA_ERRNO_INVALID_JOB ) { /* job was ripped by another thread */ } END_TRY } FINALLY { fsd_free_vector( job_ids_buf ); } END_TRY }
static void fsd_template_destroy( fsd_template_t *self ) { unsigned i; for( i = 0; i < self->n_attributes; i++ ) if( self->attributes[i] != NULL ) { const fsd_attribute_t *attr; attr = self->by_code( self, i ); if( attr ) { if( attr->is_vector ) fsd_free_vector( self->attributes[i] ); else fsd_free( self->attributes[i] ); } } fsd_free( self->attributes ); fsd_free( self ); }
void lsfdrmaa_job_set_req( fsd_drmaa_session_t *session, fsd_expand_drmaa_ph_t *expand, const fsd_template_t *jt, struct submit *req, fsd_environ_t **envp ) { const char *input_path_orig = NULL; const char *output_path_orig = NULL; const char *error_path_orig = NULL; char *volatile input_path = NULL; char *volatile output_path = NULL; char *volatile error_path = NULL; bool input_host = false; bool output_host = false; bool error_host = false; bool join_files = false; bool transfer_input = false; bool transfer_output = false; bool transfer_error = false; const char *job_category = "default"; char **volatile argv = NULL; const char *value; const char *const *vector; /* set default lsf configs */ { int i = 0; req->options = 0; req->options2 = 0; for( i = 0; i < LSF_RLIM_NLIMITS; i++ ) req->rLimits[i] = DEFAULT_RLIMIT; req->beginTime = 0; req->termTime = 0; } /* job category */ value = jt->get_attr( jt, DRMAA_JOB_CATEGORY ); if( value ) job_category = value; { fsd_conf_option_t *category_value = NULL; category_value = fsd_conf_dict_get( session->job_categories, job_category ); if( category_value != NULL ) { if( category_value->type != FSD_CONF_STRING ) fsd_exc_raise_fmt( FSD_ERRNO_INTERNAL_ERROR, "configuration error: job category should be string" ); lsfdrmaa_native_parse( category_value->val.string, req ); } else { if( value != NULL ) fsd_exc_raise_fmt( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "invalid job category: %s", job_category ); } } /* job working directory */ value = jt->get_attr( jt, DRMAA_WD ); if( value ) { char *cwd = NULL; cwd = expand->expand( expand, fsd_strdup(value), FSD_DRMAA_PH_HD | FSD_DRMAA_PH_INCR ); expand->set( expand, FSD_DRMAA_PH_WD, cwd ); #ifdef SUB3_CWD req->cwd = fsd_strdup( cwd ); req->options3 |= SUB3_CWD; #else fsd_exc_raise_fmt(FSD_ERRNO_INTERNAL_ERROR, "DRMAA_WD attribute is not supported in this version of LSF."); #endif } TRY { const char *command = NULL; unsigned n_args = 0; const char *const *i; int j; /* remote command */ command = jt->get_attr( jt, DRMAA_REMOTE_COMMAND ); if( command == NULL ) fsd_exc_raise_msg( FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES, "drmaa_remote_command not set for job template" ); /* arguments list */ vector = jt->get_v_attr( jt, DRMAA_V_ARGV ); if( vector ) { for( i = vector; *i; i++ ) n_args++; } fsd_calloc( argv, n_args+3, char* ); argv[0] = fsd_strdup("exec"); argv[1] = expand->expand( expand, fsd_strdup(command), FSD_DRMAA_PH_HD | FSD_DRMAA_PH_WD ); if( vector ) { for( i = vector, j = 2; *i; i++, j++ ) argv[j] = expand->expand( expand, fsd_strdup(*i), FSD_DRMAA_PH_HD | FSD_DRMAA_PH_WD ); } req->command = lsfdrmaa_job_quote_command( (const char*const*)argv ); } FINALLY { fsd_free_vector( argv ); } END_TRY /* job name */ value = jt->get_attr( jt, DRMAA_JOB_NAME ); if( value ) { req->jobName = fsd_strdup(value); req->options |= SUB_JOB_NAME; } /* job state at submit */ value = jt->get_attr( jt, DRMAA_JS_STATE ); if( value ) { if( 0 == strcmp( value, DRMAA_SUBMISSION_STATE_ACTIVE ) ) req->options2 &= !SUB2_HOLD; else if( 0 == strcmp( value, DRMAA_SUBMISSION_STATE_HOLD ) ) req->options2 |= SUB2_HOLD; else fsd_exc_raise_msg( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "invalid value of drmaa_js_state attribute" ); } /* environment */ vector = jt->get_v_attr( jt, DRMAA_V_ENV ); if( vector ) { fsd_environ_t *env; *envp = env = fsd_environ_new( NULL ); env->update( env, vector ); } /* start time */ value = jt->get_attr( jt, DRMAA_START_TIME ); if( value ) { req->beginTime = fsd_datetime_parse( value ); fsd_log_debug(( "\n drmaa_start_time: %s -> %ld", value, (long)req->beginTime )); } TRY { /* input path */ input_path_orig = jt->get_attr( jt, DRMAA_INPUT_PATH ); if( input_path_orig ) { input_path = internal_map_file( expand, input_path_orig, &input_host, "input" ); fsd_log_debug(( "\n drmaa_input_path: %s -> %s", input_path_orig, input_path )); } /* output path */ output_path_orig = jt->get_attr( jt, DRMAA_OUTPUT_PATH ); if( output_path_orig ) { output_path = internal_map_file( expand, output_path_orig, &output_host, "output" ); fsd_log_debug(( "\n drmaa_output_path: %s -> %s", output_path_orig, output_path )); } /* error path */ error_path_orig = jt->get_attr( jt, DRMAA_ERROR_PATH ); if( error_path_orig ) { error_path = internal_map_file( expand, error_path_orig, &error_host, "error" ); fsd_log_debug(( "\n drmaa_error_path: %s -> %s", error_path_orig, error_path )); } /* join files */ value = jt->get_attr( jt, DRMAA_JOIN_FILES ); if( value ) { if( (value[0] == 'y' || value[0] == 'Y') && value[1] == '\0' ) join_files = true; else if( (value[0] == 'n' || value[0] == 'N') && value[1] == '\0' ) join_files = false; else fsd_exc_raise_msg( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "invalid value of drmaa_join_files attribute" ); } if( join_files ) { /* * LSF by default joins output and error streams * when error file is not set. */ if( error_path ) { if( output_path == NULL ) fsd_exc_raise_msg( FSD_DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES, "drmaa_join_files is set and output file is not given" ); if( 0 != strcmp( output_path, error_path ) ) fsd_log_warning(( "Error file was given but will be ignored " "since drmaa_join_files was set." )); fsd_free( error_path ); error_path = NULL; } } else { /* * If error path is not set, we must set it to /dev/null * to prevent joining files. */ if( error_path == NULL && output_path ) error_path = fsd_strdup( "/dev/null" ); if( output_path == NULL && error_path ) output_path = fsd_strdup( "/dev/null" ); if( req->errFile == NULL ) { req->errFile = fsd_strdup( "/dev/null" ); req->options |= SUB_ERR_FILE; #ifdef SUB2_OVERWRITE_ERR_FILE req->options2 &= ~SUB2_OVERWRITE_ERR_FILE; #endif } } /* transfer files */ value = jt->get_attr( jt, DRMAA_TRANSFER_FILES ); if( value ) { const char *i; for( i = value; *i; i++ ) { switch( *i ) { case 'i': transfer_input = true; break; case 'o': transfer_output = true; break; case 'e': transfer_error = true; break; default: fsd_exc_raise_fmt( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "invalid character '%c' in drmaa_transfer_files: %s", *i, value ); } } } # if 0 { /* * Input file is transfered by LSF from submission host whenever * it isn't found on execution host regardless of explicit file transfers. * When drmaa_transfer_files contains ``i`` input file is send * explicitly because it may be outdated or otherwise differ. */ static const char *name[3] = {"input", "output", "error"}; static const int options[3] = { XF_OP_SUB2EXEC, XF_OP_EXEC2SUB, XF_OP_EXEC2SUB }; const char *path[3]; bool host[3], transfer[3]; int i; path[i=0] = input_path; path[++i] = output_path; path[++i] = error_path; host[i=0] = input_host; host[++i] = output_host; host[++i] = error_host; transfer[i=0] = transfer_input; transfer[++i] = transfer_output; transfer[++i] = transfer_error; for( i = 0; i < 3; i++ ) { struct xFile *t; if( !(transfer[i] && path[i] != NULL) ) continue; if( 0 == strcmp( path[i], "/dev/null" ) ) continue; if( host[i] ) fsd_log_warning(( "hostname in drmaa_%s_path ignored", name[i] )); fsd_log_debug(( "setting transfer of %s file (%s) " "to execution host", name[i], path[i] )); fsd_realloc( req->xf, req->nxf+1, struct xFile ); t = &req->xf[ req->nxf++ ]; memset( t, 0, sizeof(struct xFile) ); if( sizeof(t->subFn) == MAXFILENAMELEN ) { /* LSF 6 */ strlcpy( t->subFn, path[i], MAXFILENAMELEN ); strlcpy( t->execFn, path[i], MAXFILENAMELEN ); } else { /* LSF 7 */ *(char**)&t->subFn = fsd_strdup( path[i] ); *(char**)&t->execFn = fsd_strdup( path[i] ); } t->options = options[i]; } if( req->nxf > 0 ) req->options |= SUB_OTHER_FILES; } # endif /* transfer files */ /* email addresses to send notifications */ vector = jt->get_v_attr( jt, DRMAA_V_EMAIL ); if( vector && vector[0] ) { /* only to one email address message may be send */ req->mailUser = fsd_strdup( vector[0] ); req->options |= SUB_MAIL_USER | SUB_NOTIFY_END; #if 0 if( vector[1] != NULL ) fsd_log_warning(( "LSF only supports one e-mail " "notification address" )); #endif } /* block email */ value = jt->get_attr( jt, DRMAA_BLOCK_EMAIL ); if( value ) { bool block; if( strcmp(value, "1") == 0 ) block = true; else if( strcmp(value, "0") == 0 ) block = false; else fsd_exc_raise_msg( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "invalid value of drmaa_block_email attribute" ); if( block ) { if( output_path == NULL ) { fsd_log_debug(( "output path not set and we want to block e-mail, " "set to /dev/null" )); output_path = fsd_strdup( "/dev/null" ); } req->options &= ~SUB_NOTIFY_END; } else { /* SUB_NOTIFY_END should force sending e-mail even if outfile is set */ req->options |= SUB_NOTIFY_END; } } if( !((lsfdrmaa_session_t*)session)->prepand_report_to_output && (req->options & SUB_NOTIFY_END) == 0 && output_path != NULL ) { req->options |= SUB_MAIL_USER | SUB_NOTIFY_END; fsd_free( req->mailUser ); /* when email was set but notification was blocked */ req->mailUser = fsd_strdup( "notexistent" ); } if( input_path ) { req->inFile = input_path; req->options |= SUB_IN_FILE; input_path = NULL; } if( output_path ) { req->outFile = output_path; req->options |= SUB_OUT_FILE; #ifdef SUB2_OVERWRITE_OUT_FILE if( 0 != strcmp( output_path, "/dev/null" ) ) req->options2 |= SUB2_OVERWRITE_OUT_FILE; #endif output_path = NULL; } if( error_path ) { req->errFile = error_path; req->options |= SUB_ERR_FILE; #ifdef SUB2_OVERWRITE_ERR_FILE if( 0 != strcmp( error_path, "/dev/null" ) ) req->options2 |= SUB2_OVERWRITE_ERR_FILE; #endif error_path = NULL; } } FINALLY { fsd_free( input_path ); fsd_free( output_path ); fsd_free( error_path ); } END_TRY /* deadline time */ value = jt->get_attr( jt, DRMAA_DEADLINE_TIME ); if( value ) req->termTime = fsd_datetime_parse( value ); /* wall clock time hard limit */ value = jt->get_attr( jt, DRMAA_WCT_HLIMIT ); if( value ) req->rLimits[ LSF_RLIMIT_RUN ] = fsd_parse_timedelta( value ); /* wall clock time soft limit */ #ifdef SUB3_RUNTIME_ESTIMATION value = jt->get_attr( jt, DRMAA_WCT_SLIMIT ); if( value ) { req->options3 = SUB3_RUNTIME_ESTIMATION; req->runtimeEstimation = fsd_parse_timedelta( value ); } #endif /* duration hard limit */ value = jt->get_attr( jt, DRMAA_DURATION_HLIMIT ); if( value ) req->rLimits[ LSF_RLIMIT_CPU ] = fsd_parse_timedelta( value ); /* native specification */ value = jt->get_attr( jt, DRMAA_NATIVE_SPECIFICATION ); if( value ) lsfdrmaa_native_parse( value, req ); lsfdrmaa_dump_submit_req(req); }