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
}
Example #2
0
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 );
}
Example #3
0
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
}
Example #4
0
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;
}
Example #5
0
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 );
}
Example #7
0
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);
}