source: trunk/pbs_drmaa/submit.c @ 3

Revision 3, 18.4 KB checked in by mmamonski, 9 years ago (diff)

try to be resistant to torque restarts - avoid double disconnect == double free

Line 
1/* $Id: submit.c 386 2011-01-06 18:13:33Z mamonski $ */
2/*
3 *  FedStage DRMAA for PBS Pro
4 *  Copyright (C) 2006-2009  FedStage Systems
5 *
6 *  This program is free software: you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation, either version 3 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifdef HAVE_CONFIG_H
21#       include <config.h>
22#endif
23
24#include <unistd.h>
25#include <string.h>
26
27#include <pbs_ifl.h>
28#include <pbs_error.h>
29
30#include <drmaa_utils/conf.h>
31#include <drmaa_utils/drmaa.h>
32#include <drmaa_utils/drmaa_util.h>
33#include <drmaa_utils/datetime.h>
34#include <drmaa_utils/iter.h>
35#include <drmaa_utils/template.h>
36#include <pbs_drmaa/pbs_attrib.h>
37#include <pbs_drmaa/session.h>
38#include <pbs_drmaa/submit.h>
39#include <pbs_drmaa/util.h>
40
41
42
43#ifndef lint
44static char rcsid[]
45#       ifdef __GNUC__
46                __attribute__ ((unused))
47#       endif
48        = "$Id: submit.c 386 2011-01-06 18:13:33Z mamonski $";
49#endif
50
51static void
52pbsdrmaa_submit_destroy( pbsdrmaa_submit_t *self );
53
54static char *
55pbsdrmaa_submit_submit( pbsdrmaa_submit_t *self );
56
57static void
58pbsdrmaa_submit_eval( pbsdrmaa_submit_t *self );
59
60
61static void
62pbsdrmaa_submit_set( pbsdrmaa_submit_t *self, const char *pbs_attr,
63                char *value, unsigned placeholders );
64
65static void pbsdrmaa_submit_apply_defaults( pbsdrmaa_submit_t *self );
66static void pbsdrmaa_submit_apply_job_script( pbsdrmaa_submit_t *self );
67static void pbsdrmaa_submit_apply_job_state( pbsdrmaa_submit_t *self );
68static void pbsdrmaa_submit_apply_job_files( pbsdrmaa_submit_t *self );
69static void pbsdrmaa_submit_apply_file_staging( pbsdrmaa_submit_t *self );
70static void pbsdrmaa_submit_apply_job_resources( pbsdrmaa_submit_t *self );
71static void pbsdrmaa_submit_apply_job_environment( pbsdrmaa_submit_t *self );
72static void pbsdrmaa_submit_apply_email_notification( pbsdrmaa_submit_t *self );
73static void pbsdrmaa_submit_apply_job_category( pbsdrmaa_submit_t *self );
74
75
76pbsdrmaa_submit_t *
77pbsdrmaa_submit_new( fsd_drmaa_session_t *session,
78                const fsd_template_t *job_template, int bulk_idx )
79{
80        pbsdrmaa_submit_t *volatile self = NULL;
81        TRY
82         {
83                fsd_malloc( self, pbsdrmaa_submit_t );
84                self->session = session;
85                self->job_template = job_template;
86                self->script_filename = NULL;
87                self->destination_queue = NULL;
88                self->pbs_job_attributes = NULL;
89                self->expand_ph = NULL;
90                self->destroy = pbsdrmaa_submit_destroy;
91                self->submit = pbsdrmaa_submit_submit;
92                self->eval = pbsdrmaa_submit_eval;
93                self->set = pbsdrmaa_submit_set;
94                self->apply_defaults = pbsdrmaa_submit_apply_defaults;
95                self->apply_job_category = pbsdrmaa_submit_apply_job_category;
96                self->apply_job_script = pbsdrmaa_submit_apply_job_script;
97                self->apply_job_state = pbsdrmaa_submit_apply_job_state;
98                self->apply_job_files = pbsdrmaa_submit_apply_job_files;
99                self->apply_file_staging = pbsdrmaa_submit_apply_file_staging;
100                self->apply_job_resources = pbsdrmaa_submit_apply_job_resources;
101                self->apply_job_environment = pbsdrmaa_submit_apply_job_environment;
102                self->apply_email_notification = pbsdrmaa_submit_apply_email_notification;
103                self->apply_native_specification =
104                        pbsdrmaa_submit_apply_native_specification;
105
106                self->pbs_job_attributes = pbsdrmaa_pbs_template_new();
107                self->expand_ph = fsd_expand_drmaa_ph_new( NULL, NULL,
108                                (bulk_idx >= 0) ? fsd_asprintf("%d", bulk_idx) : NULL );
109         }
110        EXCEPT_DEFAULT
111         {
112                if( self )
113                        self->destroy( self );
114         }
115        END_TRY
116        return self;
117}
118
119
120void
121pbsdrmaa_submit_destroy( pbsdrmaa_submit_t *self )
122{
123        if( self->script_filename )
124         {
125                unlink( self->script_filename );
126                fsd_free( self->script_filename );
127         }
128        if( self->pbs_job_attributes )
129                self->pbs_job_attributes->destroy( self->pbs_job_attributes );
130        if( self->expand_ph )
131                self->expand_ph->destroy( self->expand_ph );
132        fsd_free( self->destination_queue );
133        fsd_free( self );
134}
135
136
137char *
138pbsdrmaa_submit_submit( pbsdrmaa_submit_t *self )
139{
140        volatile bool conn_lock = false;
141        struct attrl *volatile pbs_attr = NULL;
142        char *volatile job_id = NULL;
143        TRY
144         {
145                const fsd_template_t *pbs_tmpl = self->pbs_job_attributes;
146                unsigned i;
147
148                for( i = 0;  i < PBSDRMAA_N_PBS_ATTRIBUTES;  i++ )
149                 {
150                        const char *name = pbs_tmpl->by_code( pbs_tmpl, i )->name;
151                        if( name  &&  name[0] != '!' && pbs_tmpl->get_attr( pbs_tmpl, name ) )
152                         {
153                                struct attrl *p;
154                                const char *resource;
155                                const char *value;
156                                value = pbs_tmpl->get_attr( pbs_tmpl, name );
157                                fsd_malloc( p, struct attrl );
158                                memset( p, 0, sizeof(struct attrl) );
159                                p->next = pbs_attr;
160                                pbs_attr = p;
161                                resource = strchr( name, '.' );
162                                if( resource )
163                                 {
164                                        p->name = fsd_strndup( name, resource-name );
165                                        p->resource = fsd_strdup( resource+1 );
166                                 }
167                                else
168                                        p->name = fsd_strdup( name );
169                                fsd_log_debug(("set attr: %s = %s", name, value));
170                                p->value = fsd_strdup( value );
171                                p->op = SET;
172                         }
173                 }
174
175                conn_lock = fsd_mutex_lock( &self->session->drm_connection_mutex );
176retry:
177                job_id = pbs_submit( ((pbsdrmaa_session_t*)self->session)->pbs_conn,
178                                (struct attropl*)pbs_attr, self->script_filename,
179                                self->destination_queue, NULL );
180                if( job_id == NULL )
181                {
182                        if (pbs_errno == PBSE_PROTOCOL || pbs_errno == PBSE_EXPIRED)
183                         {
184                                pbsdrmaa_session_t *pbsself = (pbsdrmaa_session_t*)self->session;
185                                if (pbsself->pbs_conn >= 0 )
186                                        pbs_disconnect( pbsself->pbs_conn );
187                                sleep(1);
188                                pbsself->pbs_conn = pbs_connect( pbsself->super.contact );
189                                if( pbsself->pbs_conn < 0 )
190                                        pbsdrmaa_exc_raise_pbs( "pbs_connect" );
191                                else
192                                        goto retry;
193                         }
194                        else
195                         {
196                                pbsdrmaa_exc_raise_pbs( "pbs_submit" );
197                         }
198                }
199                conn_lock = fsd_mutex_unlock( &self->session->drm_connection_mutex );
200         }
201        EXCEPT_DEFAULT
202         {
203                fsd_free( job_id );
204                fsd_exc_reraise();
205         }
206        FINALLY
207         {
208                if( conn_lock )
209                        conn_lock = fsd_mutex_unlock( &self->session->drm_connection_mutex );
210                if( pbs_attr )
211                        pbsdrmaa_free_attrl( pbs_attr );
212         }
213        END_TRY
214        return job_id;
215}
216
217
218void
219pbsdrmaa_submit_eval( pbsdrmaa_submit_t *self )
220{
221        self->apply_defaults( self );
222        self->apply_job_category( self );
223        self->apply_job_script( self );
224        self->apply_job_state( self );
225        self->apply_job_files( self );
226        self->apply_file_staging( self );
227        self->apply_job_resources( self );
228        self->apply_job_environment( self );
229        self->apply_email_notification( self );
230        self->apply_native_specification( self, NULL );
231}
232
233
234void
235pbsdrmaa_submit_set( pbsdrmaa_submit_t *self, const char *name,
236                 char *value, unsigned placeholders )
237{
238        fsd_template_t *pbs_attr = self->pbs_job_attributes;
239        TRY
240         {
241                if( placeholders )
242                        value = self->expand_ph->expand(
243                                        self->expand_ph, value, placeholders );
244                pbs_attr->set_attr( pbs_attr, name, value );
245         }
246        FINALLY
247         {
248                fsd_free( value );
249         }
250        END_TRY
251}
252
253
254void
255pbsdrmaa_submit_apply_defaults( pbsdrmaa_submit_t *self )
256{
257        fsd_template_t *pbs_attr = self->pbs_job_attributes;
258        pbs_attr->set_attr( pbs_attr, PBSDRMAA_CHECKPOINT, "u" );
259        pbs_attr->set_attr( pbs_attr, PBSDRMAA_KEEP_FILES, "n" );
260        pbs_attr->set_attr( pbs_attr, PBSDRMAA_PRIORITY, "0" );
261}
262
263
264void
265pbsdrmaa_submit_apply_job_script( pbsdrmaa_submit_t *self )
266{
267        const fsd_template_t *jt = self->job_template;
268        /* fsd_template_t *pbs_attr = self->pbs_job_attributes; */
269        fsd_expand_drmaa_ph_t *expand = self->expand_ph;
270        char *script = NULL;
271        size_t script_len;
272        const char *executable;
273        const char *wd;
274        const char *const *argv;
275        const char *input_path;
276        const char *const *i;
277
278        executable   = jt->get_attr( jt, DRMAA_REMOTE_COMMAND );
279        wd           = jt->get_attr( jt, DRMAA_WD );
280        argv         = jt->get_v_attr( jt, DRMAA_V_ARGV );
281        input_path   = jt->get_attr( jt, DRMAA_INPUT_PATH );
282
283        if( wd )
284         {
285                char *cwd = NULL;
286                cwd = expand->expand( expand, fsd_strdup(wd),
287                                FSD_DRMAA_PH_HD | FSD_DRMAA_PH_INCR );
288                expand->set( expand, FSD_DRMAA_PH_WD, cwd );
289         }
290
291        if( executable == NULL )
292                fsd_exc_raise_code( FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE );
293
294        if( input_path != NULL )
295         {
296                if( input_path[0] == ':' )
297                        input_path++;
298         }
299
300         { /* compute script length */
301                script_len = 0;
302                if( wd != NULL )
303                        script_len += strlen("cd ") + strlen(wd) + strlen("; ");
304                script_len += strlen("exec ") + strlen(executable);
305                if( argv != NULL )
306                        for( i = argv;  *i != NULL;  i++ )
307                                script_len += 3+strlen(*i);
308                if( input_path != NULL )
309                        script_len += strlen(" <") + strlen(input_path);
310         }
311
312        fsd_calloc( script, script_len+1, char );
313
314         {
315                char *s;
316                s = script;
317                if( wd != NULL )
318                        s += sprintf( s, "cd %s; ", wd );
319                s += sprintf( s, "exec %s", executable );
320                if( argv != NULL )
321                        for( i = argv;  *i != NULL;  i++ )
322                                s += sprintf( s, " '%s'", *i );
323                if( input_path != NULL )
324                        s += sprintf( s, " <%s", input_path );
325                fsd_assert( s == script+script_len );
326         }
327
328        script = expand->expand( expand, script,
329                        FSD_DRMAA_PH_HD | FSD_DRMAA_PH_WD | FSD_DRMAA_PH_INCR );
330
331        /* pbs_attr->set_attr( pbs_attr, "!script", script ); */
332
333        self->script_filename = pbsdrmaa_write_tmpfile( script, strlen(script) );
334        fsd_free( script );
335}
336
337
338void
339pbsdrmaa_submit_apply_job_state( pbsdrmaa_submit_t *self )
340{
341        const fsd_template_t *jt = self->job_template;
342        fsd_template_t *pbs_attr = self->pbs_job_attributes;
343        const char *job_name = NULL;
344        const char *submit_state = NULL;
345        const char *drmaa_start_time = NULL;
346
347        job_name = jt->get_attr( jt, DRMAA_JOB_NAME );
348        submit_state = jt->get_attr( jt, DRMAA_JS_STATE );
349        drmaa_start_time = jt->get_attr( jt, DRMAA_START_TIME );
350
351        if( job_name != NULL )
352                pbs_attr->set_attr( pbs_attr, PBSDRMAA_JOB_NAME, job_name );
353
354        if( submit_state != NULL )
355         {
356                const char *hold_types;
357                if( !strcmp(submit_state, DRMAA_SUBMISSION_STATE_ACTIVE) )
358                        hold_types = "n";
359                else if( !strcmp(submit_state, DRMAA_SUBMISSION_STATE_HOLD) )
360                        hold_types = "u";
361                else
362                        fsd_exc_raise_fmt( FSD_ERRNO_INVALID_VALUE,
363                                        "invalid value of %s attribute (%s|%s)",
364                                        DRMAA_JS_STATE, DRMAA_SUBMISSION_STATE_ACTIVE,
365                                        DRMAA_SUBMISSION_STATE_HOLD );
366                pbs_attr->set_attr( pbs_attr, PBSDRMAA_HOLD_TYPES, hold_types );
367         }
368
369        if( drmaa_start_time != NULL )
370         {
371                time_t start_time;
372                char pbs_start_time[20];
373                struct tm start_time_tm;
374                start_time = fsd_datetime_parse( drmaa_start_time );
375                localtime_r( &start_time, &start_time_tm );
376                sprintf( pbs_start_time, "%04d%02d%02d%02d%02d.%02d",
377                                start_time_tm.tm_year + 1900,
378                                start_time_tm.tm_mon + 1,
379                                start_time_tm.tm_mday,
380                                start_time_tm.tm_hour,
381                                start_time_tm.tm_min,
382                                start_time_tm.tm_sec
383                                );
384                pbs_attr->set_attr( pbs_attr, PBSDRMAA_EXECUTION_TIME, pbs_start_time );
385         }
386}
387
388
389void
390pbsdrmaa_submit_apply_job_files( pbsdrmaa_submit_t *self )
391{
392        const fsd_template_t *jt = self->job_template;
393        fsd_template_t *pbs_attr = self->pbs_job_attributes;
394        const char *join_files;
395        bool b_join_files;
396        int i;
397
398        for( i = 0;  i < 2;  i++ )
399         {
400                const char *drmaa_name;
401                const char *pbs_name;
402                const char *path;
403
404                if( i == 0 )
405                 {
406                        drmaa_name = DRMAA_OUTPUT_PATH;
407                        pbs_name = PBSDRMAA_OUTPUT_PATH;
408                 }
409                else
410                 {
411                        drmaa_name = DRMAA_ERROR_PATH;
412                        pbs_name = PBSDRMAA_ERROR_PATH;
413                 }
414
415                path = jt->get_attr( jt, drmaa_name );
416                if( path != NULL )
417                 {
418                        if( path[0] == ':' )
419                                path++;
420                        self->set(self, pbs_name, fsd_strdup(path), FSD_DRMAA_PH_HD | FSD_DRMAA_PH_WD | FSD_DRMAA_PH_INCR);
421                 }
422         }
423
424        join_files = jt->get_attr( jt, DRMAA_JOIN_FILES );
425        b_join_files = join_files != NULL  &&  !strcmp(join_files,"1");
426        pbs_attr->set_attr( pbs_attr, PBSDRMAA_JOIN_FILES, (b_join_files ? "y" : "n") );
427}
428
429
430void
431pbsdrmaa_submit_apply_file_staging( pbsdrmaa_submit_t *self )
432{
433        /* TODO */
434}
435
436
437void
438pbsdrmaa_submit_apply_job_resources( pbsdrmaa_submit_t *self )
439{
440        const fsd_template_t *jt = self->job_template;
441        fsd_template_t *pbs_attr = self->pbs_job_attributes;
442        const char *cpu_time_limit = NULL;
443        const char *walltime_limit = NULL;
444
445        cpu_time_limit = jt->get_attr( jt, DRMAA_DURATION_HLIMIT );
446        walltime_limit = jt->get_attr( jt, DRMAA_WCT_HLIMIT );
447        if( cpu_time_limit )
448         {
449                pbs_attr->set_attr( pbs_attr, "Resource_List.pcput", cpu_time_limit );
450                pbs_attr->set_attr( pbs_attr, "Resource_List.cput", cpu_time_limit );
451         }
452        if( walltime_limit )
453                pbs_attr->set_attr( pbs_attr, "Resource_List.walltime", walltime_limit );
454}
455
456void
457pbsdrmaa_submit_apply_job_environment( pbsdrmaa_submit_t *self )
458{
459        const fsd_template_t *jt = self->job_template;
460        const char *const *env_v;
461
462        env_v = jt->get_v_attr( jt, DRMAA_V_ENV);
463
464        if (env_v)
465        {
466                char *env_c = NULL;
467                int ii = 0, len = 0;
468
469                ii = 0;
470                while (env_v[ii]) {
471                        len += strlen(env_v[ii]) + 1;
472                        ii++;
473                }
474
475                fsd_calloc(env_c, len + 1, char);
476                env_c[0] = '\0';
477
478                ii = 0;
479                while (env_v[ii]) {
480                        strcat(env_c, env_v[ii]);
481                        strcat(env_c, ",");
482                        ii++;
483                }
484
485                env_c[strlen(env_c) -1 ] = '\0'; /*remove the last ',' */
486
487                self->pbs_job_attributes->set_attr(self->pbs_job_attributes, "Variable_List", env_c);
488
489                fsd_free(env_c);
490        }
491}
492
493
494void
495pbsdrmaa_submit_apply_email_notification( pbsdrmaa_submit_t *self )
496{
497        /* TODO */
498}
499
500
501void
502pbsdrmaa_submit_apply_job_category( pbsdrmaa_submit_t *self )
503{
504        const char *job_category = NULL;
505        const char *category_spec = NULL;
506        fsd_conf_option_t *value = NULL;
507
508        job_category = self->job_template->get_attr(
509                        self->job_template, DRMAA_JOB_CATEGORY );
510        if( job_category == NULL  ||  job_category[0] == '\0' )
511                job_category = "default";
512        value = fsd_conf_dict_get( self->session->job_categories,
513                        job_category );
514        if( value != NULL  &&  value->type == FSD_CONF_STRING )
515                category_spec = value->val.string;
516        if( category_spec != NULL )
517                self->apply_native_specification( self, category_spec );
518}
519
520static void parse_resources(fsd_template_t *pbs_attr,const char *resources)
521{
522        char * volatile name = NULL;
523        char *arg = NULL;
524        char *value = NULL;
525        char *ctxt = NULL;
526        char * volatile resources_copy = fsd_strdup(resources);
527
528        TRY
529          {
530                for (arg = strtok_r(resources_copy, ",", &ctxt); arg; arg = strtok_r(NULL, ",",&ctxt) )
531                {
532                        char *psep = strchr(arg, '=');
533
534                        if (psep)
535                        {
536                                *psep = '\0';
537                                name = fsd_asprintf("Resource_List.%s", arg);
538                                value = ++psep;
539                                pbs_attr->set_attr( pbs_attr, name , value );
540                                fsd_free(name);
541                                name = NULL;
542                        }
543                        else
544                        {
545                                fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE, "Invalid native specification: %s (Invalid resource specification: %s)", resources, arg);
546
547                        }
548                }
549          }
550        FINALLY
551          {
552                fsd_free(name);
553                fsd_free(resources_copy);
554          }
555        END_TRY
556}
557
558static void parse_additional_attr(fsd_template_t *pbs_attr,const char *add_attr)
559{
560        char * volatile name = NULL;
561        char *arg = NULL;
562        char *value = NULL;
563        char *ctxt = NULL, *ctxt2 = NULL;
564        char * volatile add_attr_copy = fsd_strdup(add_attr);
565
566        TRY
567          {
568                for (arg = strtok_r(add_attr_copy, ",", &ctxt); arg; arg = strtok_r(NULL, ":",&ctxt) )
569                {
570                        name = fsd_strdup(strtok_r(arg, "=", &ctxt2));
571                        value = strtok_r(NULL, "=", &ctxt2);
572                        pbs_attr->set_attr( pbs_attr, name , value );
573                        fsd_free(name);
574                        name = NULL;
575                }
576          }
577        FINALLY
578          {
579                fsd_free(name);
580                fsd_free(add_attr_copy);
581          }
582        END_TRY
583}
584
585
586void
587pbsdrmaa_submit_apply_native_specification( pbsdrmaa_submit_t *self,
588                const char *native_specification )
589{
590        if( native_specification == NULL )
591                native_specification = self->job_template->get_attr(
592                                self->job_template, DRMAA_NATIVE_SPECIFICATION );
593        if( native_specification == NULL )
594                return;
595
596        {
597                fsd_iter_t * volatile args_list = fsd_iter_new(NULL, 0);
598                fsd_template_t *pbs_attr = self->pbs_job_attributes;
599                char *arg = NULL;
600                volatile char * native_spec_copy = fsd_strdup(native_specification);
601                char * ctxt = NULL;
602                int opt = 0;
603
604                TRY
605                 {
606                        for (arg = strtok_r(native_spec_copy, " \t", &ctxt); arg; arg = strtok_r(NULL, " \t",&ctxt) ) {
607                                if (!opt) {
608                                        if ( (arg[0] != '-') || ((strlen(arg) != 2) &&  arg[2] != ' ' && arg[1] !='-' ) )
609                                                fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
610                                                                "Invalid native specification: %s",
611                                                                native_specification);
612                                        if(arg[1] == '-') {
613                                                parse_additional_attr(pbs_attr, arg+2);
614                                        }
615                                        else {
616                                                opt = arg[1];
617                                        }
618                                       
619                                } else {
620                                        switch (opt) {
621                                               
622                                                case 'W' :
623                                                        parse_additional_attr(pbs_attr, arg);
624                                                        break;
625                                                case 'N' :
626                                                        pbs_attr->set_attr( pbs_attr, "Job_Name" , arg );
627                                                        break;
628                                                case 'o' :
629                                                        pbs_attr->set_attr( pbs_attr, "Output_Path" , arg );
630                                                        break;
631                                                case 'e' :
632                                                        pbs_attr->set_attr( pbs_attr, "Error_Path" , arg );
633                                                        break;
634                                                case 'j' :
635                                                        pbs_attr->set_attr( pbs_attr, "Join_Path" , arg );
636                                                        break;
637                                                case 'm' :
638                                                        pbs_attr->set_attr( pbs_attr, "Mail_Points" , arg );
639                                                        break;
640                                                case 'a' :
641                                                        pbs_attr->set_attr( pbs_attr, "Execution_Time" , arg );
642                                                        break;
643                                                case 'h' :
644                                                        pbs_attr->set_attr( pbs_attr, "Hold_Types" , arg );
645                                                        break;
646                                                case 'A' :
647                                                        pbs_attr->set_attr( pbs_attr, "Account_Name" , arg );
648                                                        break;
649                                                case 'c' :
650                                                        pbs_attr->set_attr( pbs_attr, "Checkpoint" , arg );
651                                                        break;
652                                                case 'k' :
653                                                        pbs_attr->set_attr( pbs_attr, "Keep_Files" , arg );
654                                                        break;
655                                                case 'p' :
656                                                        pbs_attr->set_attr( pbs_attr, "Priority" , arg );
657                                                        break;
658                                                case 'q' :
659                                                        self->destination_queue = fsd_strdup( arg );
660                                                        break;
661                                                case 'r' :
662                                                        pbs_attr->set_attr( pbs_attr, "Rerunable" , arg );
663                                                        break;
664                                                case 'S' :
665                                                        pbs_attr->set_attr( pbs_attr, "Shell_Path_List" , arg );
666                                                        break;
667                                                case 'u' :
668                                                        pbs_attr->set_attr( pbs_attr, "User_List" , arg );
669                                                        break;
670                                                case 'v' :
671                                                case 'V' :
672                                                        pbs_attr->set_attr( pbs_attr, "Variable_List" , arg );
673                                                        break;
674                                                case 'M' :
675                                                        pbs_attr->set_attr( pbs_attr, "Mail_Users" , arg );
676                                                        break;
677                                                case 'l' :
678                                                        parse_resources(pbs_attr, arg);
679                                                        break;                                                 
680                                                default :
681                                                       
682                                                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
683                                                                        "Invalid native specification: %s (Unsupported option: -%c)",
684                                                                        native_specification, opt);
685                                        }
686
687                                        opt = 0;
688                                }
689                        }
690
691                        if (opt) /* option without optarg */
692                                fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
693                                                "Invalid native specification: %s",
694                                                native_specification);
695
696                 }
697                FINALLY
698                 {
699#ifndef PBS_PROFESSIONAL
700                        pbs_attr->set_attr( pbs_attr, "submit_args", native_specification);
701#endif
702                        args_list->destroy(args_list);
703                        fsd_free(native_spec_copy);
704                 }
705                END_TRY
706        }
707}
708
Note: See TracBrowser for help on using the repository browser.