@@ -376,8 +376,7 @@ static int parse_res_level (struct list_ctx *ctx,
376376
377377/* Return basename of path if there is a '/' in path. Otherwise return
378378 * full path */
379- static const char *
380- parse_job_name (const char * path )
379+ static const char * parse_job_name (const char * path )
381380{
382381 char * p = strrchr (path , '/' );
383382 if (p ) {
@@ -398,6 +397,7 @@ static int jobspec_parse (struct list_ctx *ctx,
398397 json_error_t error ;
399398 json_t * jobspec = NULL ;
400399 json_t * tasks , * resources , * command , * jobspec_job = NULL ;
400+ struct res_level res [3 ];
401401 int rc = -1 ;
402402
403403 if (!(jobspec = json_loads (s , 0 , & error ))) {
@@ -489,13 +489,33 @@ static int jobspec_parse (struct list_ctx *ctx,
489489 goto nonfatal_error ;
490490 }
491491
492+ /* For jobspec version 1, expect either:
493+ * - node->slot->core->NIL
494+ * - slot->core->NIL
495+ */
496+ memset (res , 0 , sizeof (res ));
497+ if (parse_res_level (ctx , job , resources , & res [0 ]) < 0 )
498+ goto nonfatal_error ;
499+ if (res [0 ].with && parse_res_level (ctx , job , res [0 ].with , & res [1 ]) < 0 )
500+ goto nonfatal_error ;
501+ if (res [1 ].with && parse_res_level (ctx , job , res [1 ].with , & res [2 ]) < 0 )
502+ goto nonfatal_error ;
503+
504+ /* Set job->nnodes if available. In jobspec version 1, only if
505+ * resources listed as node->slot->core->NIL
506+ */
507+ if (res [0 ].type != NULL && !strcmp (res [0 ].type , "node" )
508+ && res [1 ].type != NULL && !strcmp (res [1 ].type , "slot" )
509+ && res [2 ].type != NULL && !strcmp (res [2 ].type , "core" )
510+ && res [2 ].with == NULL )
511+ job -> nnodes = res [0 ].count ;
512+
492513 /* Set job->ntasks
493514 */
494515 if (json_unpack_ex (tasks , NULL , 0 ,
495516 "[{s:{s:i}}]" ,
496517 "count" , "total" , & job -> ntasks ) < 0 ) {
497518 int per_slot , slot_count = 0 ;
498- struct res_level res [3 ];
499519
500520 if (json_unpack_ex (tasks , & error , 0 ,
501521 "[{s:{s:i}}]" ,
@@ -511,18 +531,6 @@ static int jobspec_parse (struct list_ctx *ctx,
511531 __FUNCTION__ , (uintmax_t )job -> id , per_slot );
512532 goto nonfatal_error ;
513533 }
514- /* For jobspec version 1, expect either:
515- * - node->slot->core->NIL
516- * - slot->core->NIL
517- * Set job->slot_count and job->cores_per_slot.
518- */
519- memset (res , 0 , sizeof (res ));
520- if (parse_res_level (ctx , job , resources , & res [0 ]) < 0 )
521- goto nonfatal_error ;
522- if (res [0 ].with && parse_res_level (ctx , job , res [0 ].with , & res [1 ]) < 0 )
523- goto nonfatal_error ;
524- if (res [1 ].with && parse_res_level (ctx , job , res [1 ].with , & res [2 ]) < 0 )
525- goto nonfatal_error ;
526534 if (res [0 ].type != NULL && !strcmp (res [0 ].type , "slot" )
527535 && res [1 ].type != NULL && !strcmp (res [1 ].type , "core" )
528536 && res [1 ].with == NULL ) {
@@ -549,7 +557,7 @@ static int jobspec_parse (struct list_ctx *ctx,
549557 }
550558
551559 /* nonfatal error - jobspec illegal, but we'll continue on. job
552- * listing will get initialized data */
560+ * listing will return whatever data is available */
553561nonfatal_error :
554562 rc = 0 ;
555563error :
0 commit comments