From c9b4d6e0dd2e375d43e5fa9dac5f8f2c74e403ff Mon Sep 17 00:00:00 2001 From: Moe Jette <jette1@llnl.gov> Date: Tue, 5 Oct 2004 17:40:33 +0000 Subject: [PATCH] Add support in select/bluegene plugin for node-use configuration parameter. --- doc/man/man1/smap.1 | 5 +- doc/man/man5/slurm.conf.5 | 6 +- slurm/slurm.h.in | 4 +- src/common/node_select.c | 2 +- src/plugins/select/bluegene/bluegene.c | 185 ++++++++++++-------- src/plugins/select/bluegene/bluegene.conf | 14 +- src/plugins/select/bluegene/bluegene.h | 14 +- src/plugins/select/bluegene/partition_sys.h | 3 +- src/scontrol/scontrol.c | 4 +- src/slurmctld/job_mgr.c | 18 +- src/srun/opt.c | 4 +- 11 files changed, 150 insertions(+), 109 deletions(-) diff --git a/doc/man/man1/smap.1 b/doc/man/man1/smap.1 index afcf5b24e43..8e8c305be4d 100644 --- a/doc/man/man1/smap.1 +++ b/doc/man/man1/smap.1 @@ -1,4 +1,4 @@ -.TH SMAP "1" "November 2004" "smap 0.4" "Slurm components" +.TH SMAP "1" "October 2004" "smap 0.4" "Slurm components" .SH "NAME" smap \- graphically view information about SLURM jobs, partitions, and set @@ -56,6 +56,7 @@ Print version information and exit. .TP \fBAVAIL\fR Partition state: \fBup\fR or \fBdown\fR. +.TP \fBTIMELIMIT\fR Maximum time limit for any user job in days:hours:minutes:seconds. \fBinfinite\fR is used to identify @@ -138,7 +139,7 @@ has not yet been determined. .ec .SH "COPYING" -Copyright (C) 2002 The Regents of the University of California. +Copyright (C) 2004 The Regents of the University of California. Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). UCRL-CODE-2002-040. .LP diff --git a/doc/man/man5/slurm.conf.5 b/doc/man/man5/slurm.conf.5 index ba4af43a595..40987b6de56 100644 --- a/doc/man/man5/slurm.conf.5 +++ b/doc/man/man5/slurm.conf.5 @@ -1,4 +1,4 @@ -.TH "slurm.conf" "5" "September 2004" "slurm.conf 0.4" "Slurm configuration file" +.TH "slurm.conf" "5" "October 2004" "slurm.conf 0.4" "Slurm configuration file" .SH "NAME" slurm.conf \- Slurm configuration file .SH "DESCRIPTION" @@ -303,7 +303,9 @@ A value of zero indicates the node should never be set DOWN if not responding. Fully qualified pathname of a directory into which the SLURM controller, \fBslurmctld\fR, saves its state (e.g. "/usr/local/slurm/checkpoint"). SLURM state will saved here to recover from system failures. -\fBSlurmUser\fR must be able to create files in this directory. +\fBSlurmUser\fR must be able to create files in this directory. +If you have a \fBBackupController\fR configured, this location should be +readable and writable by both systems. The default value is "/tmp". If any slurm daemons terminate abnormally, their core files will also be written into this directory. diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in index bec5c150746..3fbc5b24cf3 100644 --- a/slurm/slurm.h.in +++ b/slurm/slurm.h.in @@ -164,8 +164,8 @@ enum connection_type { }; enum node_use_type { - RM_VIRTUAL, /* application uses both processors */ - RM_COPROCESSOR /* use second processor for communications */ + RM_PARTITION_COPROCESSOR_MODE, /* use extra processor for communications */ + RM_PARTITION_VIRTUAL_NODE_MODE /* application uses both processors */ }; enum select_data_type { diff --git a/src/common/node_select.c b/src/common/node_select.c index 5a68389b0c0..2032f76e1c8 100644 --- a/src/common/node_select.c +++ b/src/common/node_select.c @@ -338,7 +338,7 @@ static char *_job_conn_type_string(uint16_t inx) static char *_job_node_use_string(uint16_t inx) { - if (inx == RM_COPROCESSOR) + if (inx == RM_PARTITION_COPROCESSOR_MODE) return "coprocessor"; else return "virtual"; diff --git a/src/plugins/select/bluegene/bluegene.c b/src/plugins/select/bluegene/bluegene.c index 749c174b166..f9b02193b18 100644 --- a/src/plugins/select/bluegene/bluegene.c +++ b/src/plugins/select/bluegene/bluegene.c @@ -68,7 +68,7 @@ static void _destroy_bgl_conf_record(void* object); static void _print_bitmap(bitstr_t* bitmap); static void _process_config(); static int _parse_bgl_spec(char *in_line); -static void _find_part_type(char* nodes, rm_partition_t** return_part_type); +static bgl_conf_record_t* _find_config_by_nodes(char* nodes); static int _listfindf_conf_part_record(bgl_conf_record_t* record, char *nodes); static void _update_bgl_node_bitmap(); static void _diff_tv_str(struct timeval *tv1,struct timeval *tv2, @@ -162,7 +162,8 @@ static void _process_config() * copy_slurm_partition_list */ request_result->bgl_record_ptr = bgl_part; - request_result->part_type = (rm_partition_t*) bgl_part->part_type; + request_result->node_use = bgl_part->node_use; + request_result->part_type = bgl_part->part_type; bgl_part->alloc_part = request_result; } } @@ -203,13 +204,21 @@ static int _copy_slurm_partition_list(List slurm_part_list) * several bgl partitions, so we need to find how to * wire each of those bgl partitions. */ - while(cur_nodes != NULL){ + while (cur_nodes != NULL) { + bgl_conf_record_t *config_ptr; + config_ptr = _find_config_by_nodes(cur_nodes); + if (config_ptr == NULL) { + error("Nodes missing from bluegene.conf: %s", cur_nodes); + rc = SLURM_ERROR; + goto cleanup; + } + bgl_record = (bgl_record_t*) xmalloc(sizeof(bgl_record_t)); bgl_record->nodes = xstrdup(cur_nodes); bgl_record->slurm_part_id = xstrdup(slurm_part->name); - bgl_record->part_type = (rm_partition_t*) xmalloc(sizeof(rm_partition_t)); - _find_part_type(cur_nodes, &bgl_record->part_type); + bgl_record->node_use = config_ptr->node_use; + bgl_record->part_type = config_ptr->part_type; bgl_record->hostlist = hostlist_create(cur_nodes); bgl_record->size = hostlist_count(bgl_record->hostlist); if (node_name2bitmap(cur_nodes, false, &(bgl_record->bitmap))){ @@ -219,15 +228,15 @@ static int _copy_slurm_partition_list(List slurm_part_list) rc = SLURM_ERROR; goto cleanup; } - - if (slurm_part->min_nodes == slurm_part->max_nodes && - bgl_record->size == slurm_part->max_nodes) + + if ((slurm_part->min_nodes == slurm_part->max_nodes) + && (bgl_record->size == slurm_part->max_nodes)) bgl_record->part_lifecycle = STATIC; else bgl_record->part_lifecycle = DYNAMIC; print_bgl_record(bgl_record); list_push(bgl_list, bgl_record); - + nodes_tmp = next_ptr; cur_nodes = strtok_r(nodes_tmp, delimiter, &next_ptr); } /* end while(cur_nodes) */ @@ -294,9 +303,7 @@ extern int read_bgl_conf() /* parse what is left, non-comments */ /* partition configuration parameters */ - if ((error_code = _parse_bgl_spec(in_line))) { - error("_parse_bgl_spec error, skipping this line"); - } + error_code = _parse_bgl_spec(in_line); /* report any leftover strings on input line */ report_leftover(in_line, line_num); @@ -326,45 +333,66 @@ extern int read_bgl_conf() static int _parse_bgl_spec(char *in_line) { int error_code = SLURM_SUCCESS; - char *nodes = NULL, *part_type = NULL; + char *nodes = NULL, *node_use = NULL, *part_type = NULL; bgl_conf_record_t* new_record; error_code = slurm_parser(in_line, - "Nodes=", 's', &nodes, - "Type=", 's', &part_type, - "END"); - - /** error if you're not specifying nodes or partition type on - this line */ - if (error_code || !nodes || !part_type){ - xfree(nodes); - xfree(part_type); - return error_code; - } + "Nodes=", 's', &nodes, + "Type=", 's', &part_type, + "Use=", 's', &node_use, + "END"); - // debug("parsed nodes %s", nodes); - // debug("partition type %s", part_type); + if (error_code) + goto cleanup; + if (!nodes && !node_use && !part_type) + goto cleanup; /* only comment */ + if (!nodes && (node_use || part_type)) { + error("bluegene.conf lacks Nodes value, but has Type or Use value"); + error_code = SLURM_ERROR; + goto cleanup; + } new_record = (bgl_conf_record_t*) xmalloc(sizeof(bgl_conf_record_t)); new_record->nodes = nodes; - new_record->part_type = xmalloc(sizeof(rm_partition_t)); + nodes = NULL; /* pointer moved, nothing left to xfree */ - if (strcasecmp(part_type, "TORUS") == 0) - *(new_record->part_type) = RM_TORUS; + if (!part_type) + new_record->part_type = RM_MESH; + else if (strcasecmp(part_type, "TORUS") == 0) + new_record->part_type = RM_TORUS; else if (strcasecmp(part_type, "MESH") == 0) - *(new_record->part_type) = RM_MESH; + new_record->part_type = RM_MESH; + else { + error("_parse_bgl_spec: partition type %s invalid for nodes %s, " + "defaulting to type: MESH", part_type, new_record->nodes); + new_record->part_type = RM_MESH; + } + + if (!node_use) + new_record->node_use = RM_PARTITION_COPROCESSOR_MODE; + else if (strcasecmp(node_use, "COPROCESSOR") == 0) + new_record->node_use = RM_PARTITION_COPROCESSOR_MODE; + else if (strcasecmp(node_use, "VIRTUAL") == 0) + new_record->node_use = RM_PARTITION_VIRTUAL_NODE_MODE; else { - error("_parse_bgl_spec: partition type %s invalid for nodes %s", - part_type, nodes); - error("defaulting to type: MESH"); - *(new_record->part_type) = RM_MESH; + error("_parse_bgl_spec: node use %s invalid for nodes %s, " + "defaulting to type: COPROCESSOR", + node_use, new_record->nodes); + new_record->node_use = RM_PARTITION_COPROCESSOR_MODE; } list_push(bgl_conf_list, new_record); +#if _DEBUG + debug("_parse_bgl_spec: added nodes=%s type=%s use=%s", + new_record->nodes, convert_part_type(new_record->part_type), + convert_node_use(new_record->node_use)); +#endif + + cleanup: xfree(part_type); - /* xfree(nodes); Don't do this as we moved value into new record type */ - - return SLURM_SUCCESS; + xfree(node_use); + xfree(nodes); + return error_code; } static void _destroy_bgl_record(void* object) @@ -374,7 +402,6 @@ static void _destroy_bgl_record(void* object) if (this_record){ xfree(this_record->nodes); xfree(this_record->slurm_part_id); - xfree(this_record->part_type); if (this_record->hostlist) hostlist_destroy(this_record->hostlist); if (this_record->bitmap) @@ -391,31 +418,19 @@ static void _destroy_bgl_conf_record(void* object) bgl_conf_record_t* this_record = (bgl_conf_record_t*) object; if (this_record){ xfree(this_record->nodes); - xfree(this_record->part_type); xfree(this_record); } } /** - * search through the list of nodes,types to find the partition type - * for the given nodes + * search through the list of nodes,types to find the partition + * containing the given nodes */ -static void _find_part_type(char* nodes, rm_partition_t** return_part_type) +static bgl_conf_record_t* _find_config_by_nodes(char* nodes) { - bgl_conf_record_t* record = NULL; - - record = (bgl_conf_record_t*) list_find_first(bgl_conf_list, + return (bgl_conf_record_t*) list_find_first(bgl_conf_list, (ListFindF) _listfindf_conf_part_record, nodes); - - *return_part_type = (rm_partition_t*) xmalloc(sizeof(rm_partition_t)); - - if (record != NULL && record->part_type != NULL){ - **return_part_type = *(record->part_type); - } else { - // error("warning: nodes not found in slurm.conf, defaulting to type RM_MESH"); - **return_part_type = RM_MESH; - } } /** nodes example: 000x111 */ @@ -535,6 +550,7 @@ extern void print_bgl_record(bgl_record_t* record) info("\tsize: %d", record->size); info("\tlifecycle: %s", convert_lifecycle(record->part_lifecycle)); info("\tpart_type: %s", convert_part_type(record->part_type)); + info("\tnode_use: %s", convert_node_use(record->node_use)); if (record->hostlist){ char buffer[BUFSIZE]; @@ -565,18 +581,30 @@ extern char* convert_lifecycle(lifecycle_type_t lifecycle) return "STATIC"; } -extern char* convert_part_type(rm_partition_t* pt) +extern char* convert_part_type(rm_partition_t pt) { - switch(*pt) { - case (RM_MESH): - return "RM_MESH"; - case (RM_TORUS): - return "RM_TORUS"; - case (RM_NAV): - return "RM_NAV"; - - default: - break; + switch (pt) { + case (RM_MESH): + return "RM_MESH"; + case (RM_TORUS): + return "RM_TORUS"; + case (RM_NAV): + return "RM_NAV"; + default: + break; + } + return ""; +} + +extern char* convert_node_use(rm_partition_mode_t pt) +{ + switch (pt) { + case (RM_PARTITION_COPROCESSOR_MODE): + return "RM_COPROCESSOR"; + case (RM_PARTITION_VIRTUAL_NODE_MODE): + return "RM_VIRTUAL"; + default: + break; } return ""; } @@ -656,18 +684,27 @@ static int _find_best_partition_match(struct job_record* job_ptr, /***********************************************/ /* check the connection type specified matches */ /***********************************************/ - // debug("part type match %s ? %s", convert_part_type(&job_ptr->type), - // convert_part_type(record->part_type)); - if (!record->part_type){ - error("find_best_partition_match record->part_type is NULL"); - continue; - } - debug("conn_type %d", conn_type); - if (conn_type != *(record->part_type) && - conn_type != RM_NAV){ +#if _DEBUG + info("part type match %s ? %s", convert_part_type(conn_type), + convert_part_type(record->part_type)); +#endif + + if ((conn_type != record->part_type) + && (conn_type != RM_NAV)) { continue; } + /***********************************************/ + /* check the node_use specified matches */ + /***********************************************/ +#if _DEBUG + info("node use match %s ? %s", convert_node_use(node_use), + convert_node_use(record->node_use)); +#endif + + if (node_use != record->node_use) + continue; + /*****************************************/ /** match up geometry as "best" possible */ /*****************************************/ diff --git a/src/plugins/select/bluegene/bluegene.conf b/src/plugins/select/bluegene/bluegene.conf index 7ddcd23119f..c5ae76adfe2 100644 --- a/src/plugins/select/bluegene/bluegene.conf +++ b/src/plugins/select/bluegene/bluegene.conf @@ -1,9 +1,9 @@ - # Sample Bluegene/L plugin configuration file. See README for -# description. the BGL parititon nodes must match preconfigured SLURM -# partitions. +# description. The BGL parititon nodes must match preconfigured SLURM +# partitions. Default value for Type is Mesh. Default value for Use +# is Coprocessor. -Nodes=bgl[400x511] Type=Mesh -Nodes=bgl[600x711] Type=Torus -Nodes=bgl[422x531] Type=Torus -Nodes=bgl[622x731] Type=Mesh +Nodes=bgl[400x511] Type=Mesh Use=Virtual +Nodes=bgl[600x711] Type=Torus Use=Virtual +Nodes=bgl[422x531] Type=Torus Use=Coprocessor +Nodes=bgl[622x731] Type=Mesh Use=Coprocessor diff --git a/src/plugins/select/bluegene/bluegene.h b/src/plugins/select/bluegene/bluegene.h index e5c2eadd412..4ccf1d71e2f 100644 --- a/src/plugins/select/bluegene/bluegene.h +++ b/src/plugins/select/bluegene/bluegene.h @@ -38,6 +38,7 @@ #ifndef _RM_API_H__ typedef uint16_t pm_partition_id_t; typedef uint16_t rm_partition_t; + typedef uint16_t rm_partition_mode_t; #else rm_BGL_t *bgl; #endif @@ -54,7 +55,8 @@ typedef struct bgl_record { bitstr_t *bitmap; /* bitmap of nodes for this partition */ struct partition* alloc_part; /* the allocated partition */ int size; /* node count for the partitions */ - rm_partition_t* part_type; /* Type=Mesh/Torus/ */ + rm_partition_t part_type; /* Mesh or Torus or NAV */ + rm_partition_mode_t node_use; /* either COPROCESSOR or VIRTUAL */ } bgl_record_t; /** @@ -63,7 +65,8 @@ typedef struct bgl_record { */ typedef struct bgl_conf_record{ char* nodes; - rm_partition_t* part_type; + rm_partition_t part_type; + rm_partition_mode_t node_use; } bgl_conf_record_t; /** @@ -98,10 +101,11 @@ extern void sort_bgl_record_dec_size(List records); /** */ extern void print_bgl_record(bgl_record_t* record); -/** */ + +/* Return strings representing blue gene data types */ extern char* convert_lifecycle(lifecycle_type_t lifecycle); -/** */ -extern char* convert_part_type(rm_partition_t* pt); +extern char* convert_part_type(rm_partition_t pt); +extern char* convert_node_use(rm_partition_mode_t pt); /* bluegene_agent - detached thread periodically updates status of bluegene nodes */ extern void *bluegene_agent(void *args); diff --git a/src/plugins/select/bluegene/partition_sys.h b/src/plugins/select/bluegene/partition_sys.h index 07c3a2a33f7..51067b2c680 100644 --- a/src/plugins/select/bluegene/partition_sys.h +++ b/src/plugins/select/bluegene/partition_sys.h @@ -47,7 +47,8 @@ typedef struct partition{ #else ushort* bgl_part_id; /* ID returned from CMCS */ - ushort* part_type; /* Type=Mesh/Torus/ */ + ushort part_type; /* Type=Mesh/Torus/NAV */ + ushort node_use; /* Use=Virtual/Coprocessor */ #endif } partition_t; diff --git a/src/scontrol/scontrol.c b/src/scontrol/scontrol.c index 10e9092e1da..ed9d62a3000 100644 --- a/src/scontrol/scontrol.c +++ b/src/scontrol/scontrol.c @@ -1576,9 +1576,9 @@ _update_job (int argc, char *argv[]) } else if (strncasecmp(argv[i], "NodeUse=", 8) == 0) { if (strcasecmp(&argv[i][8], "virtual") == 0) - job_msg.node_use = RM_VIRTUAL; + job_msg.node_use = RM_PARTITION_VIRTUAL_NODE_MODE; else if (strcasecmp(&argv[i][8], "coprocessor") == 0) - job_msg.node_use = RM_COPROCESSOR; + job_msg.node_use = RM_PARTITION_COPROCESSOR_MODE; else job_msg.node_use = (uint16_t) strtol(&argv[i][8], diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index e2c27e6d692..18f998e128e 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -2137,7 +2137,6 @@ void job_time_limit(void) job_iterator = list_iterator_create(job_list); while ((job_ptr = (struct job_record *) list_next(job_iterator))) { - bool inactive_flag = false; xassert (job_ptr->magic == JOB_MAGIC); if (job_ptr->job_state != JOB_RUNNING) continue; @@ -2145,19 +2144,16 @@ void job_time_limit(void) if (slurmctld_conf.inactive_limit && (job_ptr->time_last_active <= old)) { /* job inactive, kill it */ - job_ptr->end_time = now; - job_ptr->time_limit = 1; - inactive_flag = true; + info("Inactivity time limit reached for JobId=%u", + job_ptr->job_id); + _job_timed_out(job_ptr); + continue; } if ((job_ptr->time_limit != INFINITE) && (job_ptr->end_time <= now)) { last_job_update = now; - if (inactive_flag) - info("Inactivity time limit reached for " - "JobId=%u", job_ptr->job_id); - else - info("Time limit exhausted for JobId=%u", - job_ptr->job_id); + info("Time limit exhausted for JobId=%u", + job_ptr->job_id); _job_timed_out(job_ptr); continue; } @@ -2289,7 +2285,7 @@ static int _validate_job_desc(job_desc_msg_t * job_desc_msg, int allocate, if (job_desc_msg->conn_type == (uint16_t) NO_VAL) job_desc_msg->conn_type = RM_NAV; /* try TORUS, then MESH */ if (job_desc_msg->node_use == (uint16_t) NO_VAL) - job_desc_msg->node_use = RM_COPROCESSOR; + job_desc_msg->node_use = RM_PARTITION_COPROCESSOR_MODE; if (job_desc_msg->rotate == (uint16_t) NO_VAL) job_desc_msg->rotate = true; /* default to allow rotate */ diff --git a/src/srun/opt.c b/src/srun/opt.c index 62d50c6d3c2..e10d4c77d8b 100644 --- a/src/srun/opt.c +++ b/src/srun/opt.c @@ -257,9 +257,9 @@ static int _verify_node_use(const char *arg) int len = strlen(arg); if (!strncasecmp(arg, "VIRTUAL", len)) - return RM_VIRTUAL; + return RM_PARTITION_VIRTUAL_NODE_MODE; else if (!strncasecmp(arg, "COPROCESSOR", len)) - return RM_COPROCESSOR; + return RM_PARTITION_COPROCESSOR_MODE; error("invalid --node-use argument %s ignored.", arg); return -1; -- GitLab