source: trunk/slurm_drmaa/util.c @ 28

Revision 28, 15.5 KB checked in by mmamonski, 12 years ago (diff)

new native specification attributes

  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1/*
2 * PSNC DRMAA for SLURM
3 * Copyright (C) 2011 Poznan Supercomputing and Networking Center
4 *
5 *  This program is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <drmaa_utils/common.h>
20#include <drmaa_utils/exception.h>
21#include <slurm_drmaa/util.h>
22#include <string.h>
23
24#include <time.h>
25#include <drmaa_utils/datetime.h>
26#include <drmaa_utils/datetime_impl.h>
27
28#ifndef lint
29static char rcsid[]
30#       ifdef __GNUC__
31                __attribute__ ((unused))
32#       endif
33        = "$Id$";
34#endif
35
36unsigned int
37slurmdrmaa_datetime_parse( const char *string )
38{
39#ifdef DEBUGGING
40        char dbg[256];
41#endif
42        fsd_dt_parser_t *volatile parser = NULL;
43        fsd_dt_lexer_t *volatile lexer = NULL;
44        int parse_err = 0;
45        fsd_datetime_t dt;
46
47        memset(&dt, 0, sizeof(fsd_datetime_t));
48
49        fsd_log_enter(( "(%s)", string ));
50        TRY
51         {
52                fsd_malloc( parser, fsd_dt_parser_t );
53                fsd_malloc( lexer, fsd_dt_lexer_t );
54
55                parser->lexer = lexer;
56                parser->n_errors = 0;
57                lexer->parser = parser;
58                lexer->begin = lexer->p = (unsigned char*)string;
59                lexer->end = (unsigned char*)( string + strlen(string) );
60                parse_err = fsd_dt_parse( parser, lexer );
61                if( parse_err || parser->n_errors )
62                        fsd_exc_raise_fmt(
63                                        FSD_ERRNO_INVALID_VALUE_FORMAT,
64                                        "invalid date/time format: %s", string
65                                        );
66
67                dt = parser->result;
68#ifdef DEBUGGING
69                fsd_datetime_dump( &dt, dbg, sizeof(dbg) );
70                fsd_log_debug(( "parsed: %s", dbg ));
71#endif
72        }
73        FINALLY
74         {
75                fsd_free( parser );
76                fsd_free( lexer );
77         }
78        END_TRY
79
80        fsd_log_return(( "(%s) =%u minutes", string, (unsigned)60*dt.hour+dt.minute ));
81        return 60*dt.hour+dt.minute;
82}
83
84/* taken from SLURM src/common/proc_args.c */
85static int slurmdrmaa_mail_type_parse(const char *mail_type_str)
86{
87        int rc = 0;
88
89
90        if (strcasecmp(mail_type_str, "BEGIN") == 0)
91                rc = MAIL_JOB_BEGIN;
92        else if (strcasecmp(mail_type_str, "END") == 0)
93                rc = MAIL_JOB_END;
94        else if (strcasecmp(mail_type_str, "FAIL") == 0)
95                rc = MAIL_JOB_FAIL;
96        else if (strcasecmp(mail_type_str, "REQUEUE") == 0)
97                rc = MAIL_JOB_REQUEUE;
98        else if (strcasecmp(mail_type_str, "ALL") == 0)
99                rc = MAIL_JOB_BEGIN | MAIL_JOB_END | MAIL_JOB_FAIL | MAIL_JOB_REQUEUE;
100        else
101                rc = 0; /* failure */
102
103        return rc;
104}
105
106
107enum slurm_native {
108        SLURM_NATIVE_ACCOUNT,
109        SLURM_NATIVE_ACCTG_FREQ,
110        SLURM_NATIVE_COMMENT,
111        SLURM_NATIVE_CONSTRAINT,
112        SLURM_NATIVE_CONTIGUOUS,
113        SLURM_NATIVE_EXCLUSIVE,
114        SLURM_NATIVE_MEM,
115        SLURM_NATIVE_MEM_PER_CPU,
116        SLURM_NATIVE_MINCPUS,
117        SLURM_NATIVE_NODELIST,
118        SLURM_NATIVE_NODES,
119        SLURM_NATIVE_NTASKS_PER_NODE,
120        SLURM_NATIVE_PARTITION,
121        SLURM_NATIVE_QOS,
122        SLURM_NATIVE_REQUEUE,
123        SLURM_NATIVE_RESERVATION,
124        SLURM_NATIVE_SHARE,
125        SLURM_NATIVE_JOB_NAME,
126        SLURM_NATIVE_TIME_LIMIT,
127        SLURM_NATIVE_NTASKS,
128        SLURM_NATIVE_GRES,
129        SLURM_NATIVE_NO_KILL,
130        SLURM_NATIVE_LICENSES,
131        SLURM_NATIVE_MAIL_TYPE,
132        SLURM_NATIVE_NO_REQUEUE,
133        SLURM_NATIVE_EXCLUDE
134};
135
136void
137slurmdrmaa_init_job_desc(job_desc_msg_t *job_desc)
138{
139        memset(job_desc, 0, sizeof(job_desc_msg_t));
140}
141
142void
143slurmdrmaa_free_job_desc(job_desc_msg_t *job_desc)
144{
145        unsigned i = 0;
146        fsd_log_enter(( "" ));
147        fsd_free(job_desc->account);   
148        fsd_free(job_desc->comment);
149       
150        for(i = 0;i<job_desc->env_size;i++)
151        {
152                fsd_free(job_desc->environment[i]);
153        }       
154        fsd_free(job_desc->environment);
155        fsd_free(job_desc->features);
156        fsd_free(job_desc->name);       
157        fsd_free(job_desc->mail_user);
158        fsd_free(job_desc->partition);
159        fsd_free(job_desc->qos);
160        fsd_free(job_desc->script);
161        fsd_free(job_desc->std_in);
162        fsd_free(job_desc->std_out);
163        fsd_free(job_desc->std_err);   
164        fsd_free(job_desc->work_dir);
165        fsd_free(job_desc->gres);
166        fsd_free(job_desc->exc_nodes);
167
168       
169        fsd_log_return(( "" ));
170}
171
172void
173slurmdrmaa_add_attribute(job_desc_msg_t *job_desc, unsigned attr, const char *value)
174{
175        char * ptr = NULL;
176        char * rest = NULL;
177        char * token = NULL;
178
179        switch(attr)
180        {
181                case SLURM_NATIVE_ACCOUNT:
182                        fsd_free(job_desc->account);
183                        fsd_log_debug(("# account = %s",value));
184                        job_desc->account = fsd_strdup(value);
185                        break;
186                case SLURM_NATIVE_ACCTG_FREQ:
187                        fsd_log_debug(("# acctg_freq = %s",value));
188                        job_desc->acctg_freq = fsd_atoi(value);
189                        break;
190                case SLURM_NATIVE_COMMENT:
191                        fsd_free(job_desc->comment);
192                        fsd_log_debug(("# comment = %s",value));
193                        job_desc->comment = fsd_strdup(value);
194                        break;
195                case SLURM_NATIVE_CONSTRAINT:
196                        fsd_free(job_desc->features);
197                        fsd_log_debug(("# constraints -> features = %s",value));
198                        job_desc->features = fsd_strdup(value);
199                        break;
200                case SLURM_NATIVE_CONTIGUOUS:
201                        fsd_log_debug(( "# contiguous = 1"));
202                        job_desc->contiguous = 1;
203                        break;
204                case SLURM_NATIVE_EXCLUSIVE:
205                        fsd_log_debug(( "# exclusive -> shared = 0"));
206                        job_desc->shared = 0;
207                        break;
208                case SLURM_NATIVE_MEM:
209                #if SLURM_VERSION_NUMBER < SLURM_VERSION_NUM(2,2,0)
210                        if(job_desc->job_min_memory == NO_VAL ||  fsd_atoi(value) > (int)job_desc->job_min_memory) {
211                                fsd_log_debug(("# job_min_memory = %s",value));
212                                job_desc->job_min_memory = fsd_atoi(value);
213                        }
214                #else
215                        if(job_desc->pn_min_memory == NO_VAL ||  fsd_atoi(value) > (int)job_desc->pn_min_memory) {
216                                fsd_log_debug(("# pn_min_memory = %s",value));
217                                job_desc->pn_min_memory = fsd_atoi(value);
218                        }
219                #endif
220                        else {
221                                fsd_log_debug(("mem value defined lower or equal to mem-per-cpu or value defined before"));
222                        }
223                        break;
224                case SLURM_NATIVE_MEM_PER_CPU:
225                #if SLURM_VERSION_NUMBER < SLURM_VERSION_NUM(2,2,0)
226                        if(job_desc->job_min_memory == NO_VAL ||  fsd_atoi(value) > (int)job_desc->job_min_memory) {
227                                fsd_log_debug(("# job_min_memory = %s",value));
228                                job_desc->job_min_memory = fsd_atoi(value);
229                        }
230                #else
231                        if(job_desc->pn_min_memory == NO_VAL ||  fsd_atoi(value) > (int)job_desc->pn_min_memory) {
232                                fsd_log_debug(("# pn_min_memory = %s",value));
233                                job_desc->pn_min_memory = fsd_atoi(value);
234                        }
235                #endif
236                        else {
237                                fsd_log_debug(("mem-per-cpu value defined lower or equal to mem or value defined before"));
238                        }
239                        break;
240                case SLURM_NATIVE_MINCPUS:
241                #if SLURM_VERSION_NUMBER < SLURM_VERSION_NUM(2,2,0)
242                        fsd_log_debug(("# job_min_cpus = %s",value));
243                        job_desc->job_min_cpus = fsd_atoi(value);
244                #else
245                        fsd_log_debug(("# min_cpus = %s",value));
246                        job_desc->min_cpus = fsd_atoi(value);
247                #endif
248                        break;
249                case SLURM_NATIVE_NODELIST:
250                        fsd_free(job_desc->req_nodes);
251                        fsd_log_debug(("# node-list - > req_nodes = %s",value));
252                        job_desc->req_nodes = fsd_strdup(value);
253                        break;
254                case SLURM_NATIVE_NODES:
255                        ptr = strdup(value);
256                       
257                        if((token = strtok_r(ptr,"=",&rest)) == NULL){
258                                fsd_log_error(("strtok_r returned NULL"));
259                        }
260                                               
261                        fsd_log_debug(("nodes: %s ->",value));
262                        fsd_log_debug(("# min_nodes = %s",token));
263                        job_desc->min_nodes = fsd_atoi(token);
264                                               
265                        if(strcmp(rest,"") !=0 ) {
266                                fsd_log_debug(("# max_nodes = %s",rest));
267                                job_desc->max_nodes = fsd_atoi(rest);
268                        }
269                        fsd_free(ptr);
270                        break;         
271                case SLURM_NATIVE_NTASKS_PER_NODE:
272                        fsd_log_debug(("# ntasks_per_node = %s",value));
273                        job_desc->ntasks_per_node = fsd_atoi(value);
274                        break;
275                case SLURM_NATIVE_PARTITION:
276                        fsd_free(job_desc->partition);
277                        fsd_log_debug(("# partition = %s",value));
278                        job_desc->partition = fsd_strdup(value);
279                        break;
280                case SLURM_NATIVE_QOS:
281                        fsd_free(job_desc->qos);
282                        fsd_log_debug(("# qos = %s",value));
283                        job_desc->qos = fsd_strdup(value);
284                        break;
285                case SLURM_NATIVE_REQUEUE:
286                        fsd_log_debug(( "# requeue = 1"));
287                        job_desc->requeue = 1;
288                        break;
289                case SLURM_NATIVE_RESERVATION:
290                        fsd_log_debug(("# reservation = %s",value));
291                        job_desc->reservation = fsd_strdup(value);
292                        break;
293                case SLURM_NATIVE_SHARE:
294                        fsd_log_debug(("# shared = 1"));
295                        job_desc->shared = 1;
296                        break;
297                case SLURM_NATIVE_JOB_NAME:
298                        fsd_log_debug(("# job_name = %s",job_desc->name));
299                        job_desc->name = fsd_strdup(value);
300                        break;
301                case SLURM_NATIVE_NTASKS:
302                        fsd_log_debug(("# ntasks = %s",value));
303                        job_desc->num_tasks = fsd_atoi(value);
304                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_MINCPUS,value);
305                        break; 
306                case SLURM_NATIVE_TIME_LIMIT:
307                        fsd_log_debug(("# time_limit = %s",value));
308                        job_desc->time_limit = slurmdrmaa_datetime_parse(value);
309                        break; 
310                case SLURM_NATIVE_GRES:
311                        fsd_log_debug(("# gres = %s",value));
312                        job_desc->gres = fsd_strdup(value);
313                        break;
314                case SLURM_NATIVE_NO_KILL:
315                        fsd_log_debug(("# no_kill = 1"));
316                        job_desc->kill_on_node_fail = 0;
317                        break;
318                case SLURM_NATIVE_LICENSES:
319                        fsd_log_debug(("# licenses = %s", value));
320                        job_desc->licenses = fsd_strdup(value);
321                        break;
322                case SLURM_NATIVE_MAIL_TYPE:
323                        fsd_log_debug(("# mail_type = %s", value));
324                        job_desc->mail_type = slurmdrmaa_mail_type_parse(value);
325                        break;
326                case SLURM_NATIVE_NO_REQUEUE:
327                        fsd_log_debug(("# requeue = 0"));
328                        job_desc->requeue = 0;
329                        break;
330                case SLURM_NATIVE_EXCLUDE:
331                        fsd_log_debug(("# exclude = %s", value));
332                        job_desc->exc_nodes = fsd_strdup(value);
333                        break;
334       
335                default:
336                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,"Invalid attribute");
337        }
338}
339
340void
341slurmdrmaa_parse_additional_attr(job_desc_msg_t *job_desc,const char *add_attr)
342{
343        char * volatile name = NULL;
344        char *value = NULL;
345        char *ctxt = NULL;
346        char * volatile add_attr_copy = fsd_strdup(add_attr);
347
348        TRY
349          {
350                name = fsd_strdup(strtok_r(add_attr_copy, "=", &ctxt));
351                value = strtok_r(NULL, "=", &ctxt);
352                /*
353                 * TODO: move it to slurmdrmaa_add_attribute
354                 if (value == NULL) {
355                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
356                                "Invalid native specification: %s Missing '='.", add_attr_copy);
357                } */
358
359                if(strcmp(name,"account") == 0) {
360                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_ACCOUNT,value);
361                }
362                else if(strcmp(name,"acctg-freq") == 0) {
363                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_ACCTG_FREQ,value);
364                }
365                else if (strcmp(name,"comment") == 0) {
366                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_COMMENT,value);
367                }
368                else if (strcmp(name,"constraint") == 0) {
369                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_CONSTRAINT,value);
370                }
371                else if (strcmp(name,"contiguous") == 0) {
372                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_CONTIGUOUS,NULL);
373                }
374                else if(strcmp(name,"exclusive") == 0) {
375                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_EXCLUSIVE,NULL);
376                }
377                else if (strcmp(name,"mem") == 0) {
378                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_MEM,value);
379                }
380                else if (strcmp(name,"mem-per-cpu") == 0) {
381                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_MEM_PER_CPU,value);
382                }
383                else if (strcmp(name,"mincpus") == 0) {
384                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_MINCPUS,value);
385                }
386                else if (strcmp(name,"nodelist") == 0) {
387                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NODELIST,value);                 
388                }
389                else if (strcmp(name,"nodes") == 0) {
390                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NODES,value);
391                }
392                else if (strcmp(name,"ntasks-per-node") == 0) {
393                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NTASKS_PER_NODE,value);
394                }
395                else if (strcmp(name,"partition") == 0) {
396                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_PARTITION,value);
397                }
398                else if (strcmp(name,"qos") == 0) {
399                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_QOS,value);
400                }
401                else if (strcmp(name,"requeue") == 0) {
402                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_REQUEUE,NULL);
403                }
404                else if (strcmp(name,"reservation") == 0) {
405                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_RESERVATION,value);
406                }
407                else if (strcmp(name,"share") == 0) {
408                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_SHARE,NULL);
409                }               
410                else if(strcmp(name,"job_name") == 0) {
411                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_JOB_NAME,value);
412                }
413                else if(strcmp(name,"time_limit") == 0) {
414                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_TIME_LIMIT,value);
415                }
416                else if(strcmp(name,"time") == 0) {
417                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_TIME_LIMIT,value);
418                }
419                else if(strcmp(name,"ntasks") == 0) {
420                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NTASKS,value);
421                }
422                else if(strcmp(name,"gres") == 0) {
423                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_GRES,value);
424                }
425                else if(strcmp(name,"no-kill") == 0) {
426                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NO_KILL,NULL);
427                }
428                else if(strcmp(name,"licenses") == 0) {
429                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_LICENSES,value);
430                }
431                else if(strcmp(name,"mail-type") == 0) {
432                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_MAIL_TYPE,value);
433                }
434                else if(strcmp(name,"no-requeue") == 0) {
435                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NO_REQUEUE,NULL);
436                }
437                else if(strcmp(name,"exclude") == 0) {
438                        slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_EXCLUDE,value);
439                }
440                else {
441                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
442                                        "Invalid native specification: %s (Unsupported option: --%s)",
443                                        add_attr, name);
444                }
445       
446          }
447        FINALLY
448          {
449                fsd_free(name);
450                fsd_free(add_attr_copy);
451          }
452        END_TRY
453}
454
455void
456slurmdrmaa_parse_native(job_desc_msg_t *job_desc, const char * value)
457{
458        char *arg = NULL;
459        char * volatile native_specification = fsd_strdup(value);
460        char * volatile native_spec_copy = fsd_strdup(native_specification);
461        char * ctxt = NULL;
462        int opt = 0;
463               
464        fsd_log_enter(( "" ));
465        TRY
466         {
467                for (arg = strtok_r(native_spec_copy, " \t", &ctxt); arg; arg = strtok_r(NULL, " \t",&ctxt) ) {
468                        if (!opt) {
469                                if ( (arg[0] != '-') || ((strlen(arg) != 2) && (strlen(arg) > 2) && arg[2] != ' ' && arg[1] !='-' ) ) {
470                                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
471                                                        "Invalid native specification: %s",
472                                                        native_specification);
473                                }
474                                if(arg[1] == '-') {
475                                        slurmdrmaa_parse_additional_attr(job_desc, arg+2);
476                                }
477                                else {
478                                        opt = arg[1];
479                                }               
480                        } else {
481                                switch (opt) {
482                                        case 'A' :
483                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_ACCOUNT, arg);
484                                                break;
485                                        case 'C' :
486                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_CONSTRAINT, arg);
487                                                break; 
488                                        case 'N' :     
489                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NODES, arg);
490                                                break; 
491                                        case 'p' :
492                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_PARTITION, arg);
493                                                break;
494                                        case 's' :
495                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_SHARE, NULL);
496                                                break;
497                                        case 'w' :
498                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NODELIST, arg);
499                                                break;
500                                        case 'J' :
501                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_JOB_NAME, arg);
502                                                break;
503                                        case 't' :
504                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_TIME_LIMIT, arg);
505                                                break; 
506                                        case 'n' :
507                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_NTASKS, arg);
508                                                break; 
509                                        case 'x' :
510                                                slurmdrmaa_add_attribute(job_desc,SLURM_NATIVE_EXCLUDE, arg);
511                                                break;
512                                        default :
513                                                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
514                                                                        "Invalid native specification: %s (Unsupported option: -%c)",
515                                                                        native_specification, opt);
516                                }
517                                if (arg[0] == '-' && strlen(arg) == 2) { /* attribute without arg */
518                                        opt = arg[1];
519                                }
520                                else {
521                                        opt = 0;
522                                }
523                        }
524                }
525
526                if(strlen(native_spec_copy) == 2 && native_spec_copy[0] == '-' && native_spec_copy[1] == 's')
527                {
528                        slurmdrmaa_add_attribute(job_desc, SLURM_NATIVE_SHARE, NULL);
529                        opt = 0;
530                }
531               
532                if (opt)
533                        fsd_exc_raise_fmt(FSD_DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE,
534                                        "Invalid native specification: %s",
535                                        native_specification);
536
537         }
538        FINALLY
539         {
540                fsd_free(native_spec_copy);
541                fsd_free(native_specification);
542         }
543        END_TRY
544
545        fsd_log_return(( "" ));
546}
547
Note: See TracBrowser for help on using the repository browser.