--- src/include/attribute.h.orig 2010-07-20 10:57:27.000000000 -0700 +++ src/include/attribute.h 2010-08-17 17:43:12.000000000 -0700 @@ -408,6 +408,7 @@ extern int comp_ll(attribute *, attribute *); extern int comp_size(attribute *, attribute *); extern int comp_str(attribute *, attribute *); +extern int comp_nodes(attribute *, attribute *); extern int comp_arst(attribute *, attribute *); extern int comp_resc(attribute *, attribute *); extern int comp_resc2(attribute *, attribute *, int, char *); @@ -457,6 +458,7 @@ extern int node_status_list(attribute*, void*, int); extern int node_note(attribute*, void*, int); extern int set_note_str(attribute *attr, attribute *new, enum batch_op); +extern int proc_count(char *); extern void replace_attr_string(attribute*, char*); /* Token manipulation functions */ --- src/lib/Libattr/attr_fn_str.c.orig 2010-07-20 10:57:36.000000000 -0700 +++ src/lib/Libattr/attr_fn_str.c 2010-08-18 18:37:39.000000000 -0700 @@ -339,6 +339,72 @@ /* + * comp_nodes - compare two nodes strings of the form x:ppn=y + * + * Returns: x1*y1 - x2*y2 + */ + +int +comp_nodes(struct attribute *attr, struct attribute *with) + { + int aprocs, wprocs; + + if (!attr || !attr->at_val.at_str) + return (-1); + + /* the nodes string is of the form x:ppn=y, thus extract x and y + and compare x*y */ + aprocs = proc_count(attr->at_val.at_str); + wprocs = proc_count(with->at_val.at_str); + if (aprocs < 0 || wprocs < 0) + /* fall back to strcmp */ + return (strcmp(attr->at_val.at_str, with->at_val.at_str)); + + return (aprocs - wprocs); + } + + + + +/* + * proc_count - return total no. of processors in a node spec + */ + +int proc_count(char *str) + { + int num_nodes = 0, num_procs = 0, total_procs = 0; + char *substr, *ppnloc; + + str = strdup(str); + if (str == NULL) + return(-1); + + /* split on + */ + substr = strtok(str, "+"); + do + { + num_nodes = atoi(substr); + if (num_nodes == 0) + /* no number */ + num_nodes = 1; + + ppnloc = strstr(substr, ":ppn="); + if (ppnloc == NULL) + num_procs = 1; + else + num_procs = atoi(ppnloc + 5); + + total_procs += num_procs * num_nodes; + substr = strtok(NULL, "+"); + } while(substr != NULL); + + free(str); + return(total_procs); + } + + + +/* * free_str - free space malloc-ed for string attribute value */ --- src/server/svr_jobfunc.c.orig 2010-07-30 08:17:13.000000000 -0700 +++ src/server/svr_jobfunc.c 2010-08-18 17:04:59.000000000 -0700 @@ -1038,24 +1038,18 @@ if ((jbrc->rs_defin == noderesc) && (qtype == QTYPE_Execution)) { - /* NOTE: process after loop so SvrNodeCt is loaded */ - /* can check pure nodes violation right here */ - int job_nodes; - int queue_nodes; + /* compare number of processors requested in the job's node spec + with the queue's limit */ + int nodes_diff; jbrc_nodes = jbrc; if ((jbrc_nodes != NULL) && (qurc != NULL)) { - if ((isdigit(*(jbrc_nodes->rs_value.at_val.at_str))) && - (isdigit(*(qurc->rs_value.at_val.at_str)))) - { - job_nodes = atoi(jbrc_nodes->rs_value.at_val.at_str); - queue_nodes = atoi(qurc->rs_value.at_val.at_str); + nodes_diff = comp_nodes(&qurc->rs_value, &jbrc_nodes->rs_value); - if (queue_nodes < job_nodes) - comp_resc_lt++; - } + if (nodes_diff < 0) + comp_resc_lt++; } } --- src/server/resc_def_all.c.orig 2010-07-20 10:57:35.000000000 -0700 +++ src/server/resc_def_all.c 2010-08-17 17:43:12.000000000 -0700 @@ -267,7 +267,7 @@ decode_nodes, encode_str, set_str, - comp_str, + comp_nodes, free_str, set_node_ct, READ_WRITE | ATR_DFLAG_MOM | ATR_DFLAG_RMOMIG,