static char * _get_node_state(struct node_record *node_ptr) { static bool got_select_type = false; static bool node_allocations; if (!got_select_type) { char * select_type = slurm_get_select_type(); if (select_type && (strcasecmp(select_type, "select/linear") == 0)) node_allocations = true; else node_allocations = false; xfree(select_type); got_select_type = true; } if (IS_NODE_DRAIN(node_ptr) || IS_NODE_FAIL(node_ptr)) return "Draining"; if (IS_NODE_COMPLETING(node_ptr)) return "Busy"; if (IS_NODE_DOWN(node_ptr)) return "Down"; if (IS_NODE_ALLOCATED(node_ptr)) { if (node_allocations) return "Busy"; else return "Running"; } if (IS_NODE_IDLE(node_ptr)) return "Idle"; return "Unknown"; }
static int _parse_resv_core_cnt(resv_desc_msg_t *resv_msg_ptr, char *val, bool from_tres) { char *endptr = NULL, *core_cnt, *tok, *ptrptr = NULL; char *type; int node_inx = 0; type = slurm_get_select_type(); if (strcasestr(type, "cray")) { int param; param = slurm_get_select_type_param(); if (! (param & CR_OTHER_CONS_RES)) { error("CoreCnt or CPUCnt is only " "suported when " "SelectTypeParameters " "includes OTHER_CONS_RES"); xfree(type); return SLURM_ERROR; } } else if (strcasestr(type, "cons_res") == NULL) { error("CoreCnt or CPUCnt is only " "suported when " "SelectType includes " "select/cons_res"); xfree(type); return SLURM_ERROR; } xfree(type); core_cnt = xstrdup(val); tok = strtok_r(core_cnt, ",", &ptrptr); while (tok) { xrealloc(resv_msg_ptr->core_cnt, sizeof(uint32_t) * (node_inx + 2)); resv_msg_ptr->core_cnt[node_inx] = strtol(tok, &endptr, 10); if ((endptr == NULL) || (endptr[0] != '\0') || (tok[0] == '\0')) { exit_code = 1; if (from_tres) error("Invalid TRES core count %s", val); else error("Invalid core count %s", val); xfree(core_cnt); return SLURM_ERROR; } node_inx++; tok = strtok_r(NULL, ",", &ptrptr); } xfree(core_cnt); return SLURM_SUCCESS; }
static void _load_config(void) { char *sched_params, *select_type, *tmp_ptr; sched_timeout = slurm_get_msg_timeout() / 2; sched_timeout = MAX(sched_timeout, 1); sched_timeout = MIN(sched_timeout, 10); sched_params = slurm_get_sched_params(); if (sched_params && (tmp_ptr=strstr(sched_params, "interval="))) builtin_interval = atoi(tmp_ptr + 9); if (builtin_interval < 1) { error("Invalid SchedulerParameters interval: %d", builtin_interval); builtin_interval = BACKFILL_INTERVAL; } if (sched_params && (tmp_ptr=strstr(sched_params, "max_job_bf="))) max_sched_job_cnt = atoi(tmp_ptr + 11); if (sched_params && (tmp_ptr=strstr(sched_params, "bf_max_job_test="))) max_sched_job_cnt = atoi(tmp_ptr + 16); if (max_sched_job_cnt < 1) { error("Invalid SchedulerParameters bf_max_job_test: %d", max_sched_job_cnt); max_sched_job_cnt = 50; } xfree(sched_params); select_type = slurm_get_select_type(); if (!xstrcmp(select_type, "select/serial")) { /* Do not spend time computing expected start time for * pending jobs */ max_sched_job_cnt = 0; stop_builtin_agent(); } xfree(select_type); }
/* * Initialize context for node selection plugin */ extern int slurm_select_init(bool only_default) { int retval = SLURM_SUCCESS; char *type = NULL; int i, j, len; DIR *dirp; struct dirent *e; char *dir_array = NULL, *head = NULL; char *plugin_type = "select"; if ( init_run && select_context ) return retval; slurm_mutex_lock( &select_context_lock ); if ( select_context ) goto done; type = slurm_get_select_type(); if (working_cluster_rec) { /* just ignore warnings here */ } else { #ifdef HAVE_XCPU if (strcasecmp(type, "select/linear")) { error("%s is incompatible with XCPU use", type); fatal("Use SelectType=select/linear"); } #endif if (!strcasecmp(type, "select/linear")) { uint16_t cr_type = slurm_get_select_type_param(); if ((cr_type & CR_SOCKET) || (cr_type & CR_CORE) || (cr_type & CR_CPU)) fatal("Invalid SelectTypeParameter " "for select/linear"); } #ifdef HAVE_BG if (strcasecmp(type, "select/bluegene")) { error("%s is incompatible with BlueGene", type); fatal("Use SelectType=select/bluegene"); } #else if (!strcasecmp(type, "select/bluegene")) { fatal("Requested SelectType=select/bluegene " "in slurm.conf, but not running on a BG[L|P|Q] " "system. If looking to emulate a BG[L|P|Q] " "system use --enable-bgl-emulation or " "--enable-bgp-emulation respectively."); } #endif #ifdef HAVE_ALPS_CRAY if (strcasecmp(type, "select/alps")) { error("%s is incompatible with Cray system " "running alps", type); fatal("Use SelectType=select/alps"); } #else if (!strcasecmp(type, "select/alps")) { fatal("Requested SelectType=select/alps " "in slurm.conf, but not running on a ALPS Cray " "system. If looking to emulate a Alps Cray " "system use --enable-alps-cray-emulation."); } #endif } select_context_cnt = 0; if (only_default) { ops = xmalloc(sizeof(slurm_select_ops_t)); select_context = xmalloc(sizeof(plugin_context_t)); if ((select_context[0] = plugin_context_create( plugin_type, type, (void **)&ops[0], node_select_syms, sizeof(node_select_syms)))) { select_context_default = 0; select_context_cnt++; } goto skip_load_all; } if (!(dir_array = slurm_get_plugin_dir())) { error("plugin_load_and_link: No plugin dir given"); goto done; } head = dir_array; for (i=0; ; i++) { bool got_colon = 0; if (dir_array[i] == ':') { dir_array[i] = '\0'; got_colon = 1; } else if (dir_array[i] != '\0') continue; /* Open the directory. */ if (!(dirp = opendir(head))) { error("cannot open plugin directory %s", head); goto done; } while (1) { char full_name[128]; if (!(e = readdir( dirp ))) break; /* Check only files with select_ in them. */ if (strncmp(e->d_name, "select_", 7)) continue; len = strlen(e->d_name); #if defined(__CYGWIN__) len -= 4; #else len -= 3; #endif /* Check only shared object files */ if (strcmp(e->d_name+len, #if defined(__CYGWIN__) ".dll" #else ".so" #endif )) continue; /* add one for the / */ len++; xassert(len<sizeof(full_name)); snprintf(full_name, len, "select/%s", e->d_name+7); for (j=0; j<select_context_cnt; j++) { if (!strcmp(full_name, select_context[j]->type)) break; } if (j >= select_context_cnt) { xrealloc(ops, (sizeof(slurm_select_ops_t) * (select_context_cnt + 1))); xrealloc(select_context, (sizeof(plugin_context_t) * (select_context_cnt + 1))); select_context[select_context_cnt] = plugin_context_create( plugin_type, full_name, (void **)&ops[ select_context_cnt], node_select_syms, sizeof(node_select_syms)); if (select_context[select_context_cnt]) { /* set the default */ if (!strcmp(full_name, type)) select_context_default = select_context_cnt; select_context_cnt++; } } } closedir(dirp); if (got_colon) { head = dir_array + i + 1; } else break; } skip_load_all: if (select_context_default == -1) fatal("Can't find plugin for %s", type); /* Insure that plugin_id is valid and unique */ for (i=0; i<select_context_cnt; i++) { for (j=i+1; j<select_context_cnt; j++) { if (*(ops[i].plugin_id) != *(ops[j].plugin_id)) continue; fatal("SelectPlugins: Duplicate plugin_id %u for " "%s and %s", *(ops[i].plugin_id), select_context[i]->type, select_context[j]->type); } if (*(ops[i].plugin_id) < 100) { fatal("SelectPlugins: Invalid plugin_id %u (<100) %s", *(ops[i].plugin_id), select_context[i]->type); } } init_run = true; done: slurm_mutex_unlock( &select_context_lock ); xfree(type); xfree(dir_array); return retval; }
/* * Initialize context for node selection plugin */ extern int slurm_select_init(bool only_default) { int retval = SLURM_SUCCESS; char *select_type = NULL; int i, j, rc, len; DIR *dirp; struct dirent *e; char *dir_array = NULL, *head = NULL; slurm_mutex_lock( &select_context_lock ); if ( select_context ) goto done; select_type = slurm_get_select_type(); if (working_cluster_rec) { /* just ignore warnings here */ } else { #ifdef HAVE_XCPU if (strcasecmp(select_type, "select/linear")) { error("%s is incompatible with XCPU use", select_type); fatal("Use SelectType=select/linear"); } #endif #ifdef HAVE_BG if (strcasecmp(select_type, "select/bluegene")) { error("%s is incompatible with BlueGene", select_type); fatal("Use SelectType=select/bluegene"); } #else if (!strcasecmp(select_type, "select/bluegene")) { fatal("Requested SelectType=select/bluegene " "in slurm.conf, but not running on a BG[L|P|Q] " "system. If looking to emulate a BG[L|P|Q] " "system use --enable-bgl-emulation or " "--enable-bgp-emulation respectively."); } #endif #ifdef HAVE_CRAY if (strcasecmp(select_type, "select/cray")) { error("%s is incompatible with Cray", select_type); fatal("Use SelectType=select/cray"); } #else if (!strcasecmp(select_type, "select/cray")) { fatal("Requested SelectType=select/cray " "in slurm.conf, but not running on a Cray " "system. If looking to emulate a Cray " "system use --enable-cray-emulation."); } #endif } select_context_cnt = 0; if(only_default) { select_context = xmalloc(sizeof(slurm_select_context_t)); rc = _select_get_ops(select_type, select_context); if (rc == SLURM_SUCCESS) { select_context_default = 0; select_context_cnt++; } goto skip_load_all; } if(!(dir_array = slurm_get_plugin_dir())) { error("plugin_load_and_link: No plugin dir given"); goto done; } head = dir_array; for (i=0; ; i++) { bool got_colon = 0; if (dir_array[i] == ':') { dir_array[i] = '\0'; got_colon = 1; } else if(dir_array[i] != '\0') continue; /* Open the directory. */ if(!(dirp = opendir(head))) { error("cannot open plugin directory %s", head); goto done; } while (1) { char full_name[128]; if(!(e = readdir( dirp ))) break; /* Check only files with select_ in them. */ if (strncmp(e->d_name, "select_", 7)) continue; len = strlen(e->d_name); #if defined(__CYGWIN__) len -= 4; #else len -= 3; #endif /* Check only shared object files */ if (strcmp(e->d_name+len, #if defined(__CYGWIN__) ".dll" #else ".so" #endif )) continue; /* add one for the / */ len++; xassert(len<sizeof(full_name)); snprintf(full_name, len, "select/%s", e->d_name+7); for (j=0; j<select_context_cnt; j++) { if (!strcmp(full_name, select_context[j].select_type)) break; } if (j < select_context_cnt) { error("Duplicate plugin %s ignored", select_context[j].select_type); } else { xrealloc(select_context, (sizeof(slurm_select_context_t) * (select_context_cnt + 1))); rc = _select_get_ops( full_name, select_context + select_context_cnt); /* only add the ones this system has */ if (rc == SLURM_SUCCESS) { /* set the default */ if (!strcmp(full_name, select_type)) select_context_default = select_context_cnt; select_context_cnt++; } } } closedir(dirp); if (got_colon) { head = dir_array + i + 1; } else break; } skip_load_all: if(select_context_default == -1) fatal("Can't find plugin for %s", select_type); /* Insure that plugin_id is valid and unique */ for (i=0; i<select_context_cnt; i++) { for (j=i+1; j<select_context_cnt; j++) { if (*(select_context[i].ops.plugin_id) != *(select_context[j].ops.plugin_id)) continue; fatal("SelectPlugins: Duplicate plugin_id %u for " "%s and %s", *(select_context[i].ops.plugin_id), select_context[i].select_type, select_context[j].select_type); } if (*(select_context[i].ops.plugin_id) < 100) { fatal("SelectPlugins: Invalid plugin_id %u (<100) %s", *(select_context[i].ops.plugin_id), select_context[i].select_type); } } done: slurm_mutex_unlock( &select_context_lock ); xfree(select_type); xfree(dir_array); return retval; }
/* * Initialize context for node selection plugin */ extern int slurm_select_init(bool only_default) { int retval = SLURM_SUCCESS; char *select_type = NULL; int i, j, plugin_cnt; char *plugin_type = "select"; List plugin_names = NULL; _plugin_args_t plugin_args = {0}; if ( init_run && select_context ) return retval; slurm_mutex_lock( &select_context_lock ); if ( select_context ) goto done; select_type = slurm_get_select_type(); if (working_cluster_rec) { /* just ignore warnings here */ } else { #ifdef HAVE_NATIVE_CRAY if (xstrcasecmp(select_type, "select/cray")) { error("%s is incompatible with a native Cray system.", select_type); fatal("Use SelectType=select/cray"); } #else /* if (!xstrcasecmp(select_type, "select/cray")) { */ /* fatal("Requested SelectType=select/cray " */ /* "in slurm.conf, but not running on a native Cray " */ /* "system. If looking to run on a Cray " */ /* "system natively use --enable-native-cray."); */ /* } */ #endif } select_context_cnt = 0; plugin_args.plugin_type = plugin_type; plugin_args.default_plugin = select_type; if (only_default) { plugin_names = list_create(slurm_destroy_char); list_append(plugin_names, xstrdup(select_type)); } else { plugin_names = plugin_get_plugins_of_type(plugin_type); } if (plugin_names && (plugin_cnt = list_count(plugin_names))) { ops = xcalloc(plugin_cnt, sizeof(slurm_select_ops_t)); select_context = xcalloc(plugin_cnt, sizeof(plugin_context_t *)); list_for_each(plugin_names, _load_plugins, &plugin_args); } if (select_context_default == -1) fatal("Can't find plugin for %s", select_type); /* Ensure that plugin_id is valid and unique */ for (i=0; i<select_context_cnt; i++) { for (j=i+1; j<select_context_cnt; j++) { if (*(ops[i].plugin_id) != *(ops[j].plugin_id)) continue; fatal("SelectPlugins: Duplicate plugin_id %u for " "%s and %s", *(ops[i].plugin_id), select_context[i]->type, select_context[j]->type); } if (*(ops[i].plugin_id) < 100) { fatal("SelectPlugins: Invalid plugin_id %u (<100) %s", *(ops[i].plugin_id), select_context[i]->type); } } init_run = true; done: slurm_mutex_unlock( &select_context_lock ); if (!working_cluster_rec) { if (select_running_linear_based()) { uint16_t cr_type = slurm_get_select_type_param(); if (cr_type & (CR_CPU | CR_CORE | CR_SOCKET)) { fatal("Invalid SelectTypeParameters for " "%s: %s (%u), it can't contain " "CR_(CPU|CORE|SOCKET).", select_type, select_type_param_string(cr_type), cr_type); } } } xfree(select_type); FREE_NULL_LIST(plugin_names); return retval; }
/* * scontrol_parse_res_options parse options for creating or updating a reservation * IN argc - count of arguments * IN argv - list of arguments * IN msg - a string to append to any error message * OUT resv_msg_ptr - struct holding reservation parameters * OUT free_user_str - bool indicating that resv_msg_ptr->users should be freed * OUT free_acct_str - bool indicating that resv_msg_ptr->accounts should be * freed * RET 0 on success, -1 on err and prints message */ extern int scontrol_parse_res_options(int argc, char *argv[], const char *msg, resv_desc_msg_t *resv_msg_ptr, int *free_user_str, int *free_acct_str) { int i; int duration = -3; /* -1 == INFINITE, -2 == error, -3 == not set */ *free_user_str = 0; *free_acct_str = 0; for (i=0; i<argc; i++) { char *tag = argv[i]; int taglen = 0; char plus_minus = '\0'; char *val = strchr(argv[i], '='); taglen = val - argv[i]; if (!val && strncasecmp(argv[i], "res", 3) == 0) { continue; } else if (!val || taglen == 0) { exit_code = 1; error("Unknown parameter %s. %s", argv[i], msg); return -1; } if (val[-1] == '+' || val[-1] == '-') { plus_minus = val[-1]; taglen--; } val++; if (strncasecmp(tag, "ReservationName", MAX(taglen, 1)) == 0) { resv_msg_ptr->name = val; } else if (strncasecmp(tag, "Accounts", MAX(taglen, 1)) == 0) { if (plus_minus) { resv_msg_ptr->accounts = _process_plus_minus(plus_minus, val); *free_acct_str = 1; } else { resv_msg_ptr->accounts = val; } } else if (strncasecmp(tag, "BurstBuffer", MAX(taglen, 2)) == 0) { resv_msg_ptr->burst_buffer = val; } else if (strncasecmp(tag, "StartTime", MAX(taglen, 1)) == 0){ time_t t = parse_time(val, 0); if (errno == ESLURM_INVALID_TIME_VALUE) { exit_code = 1; error("Invalid start time %s. %s", argv[i], msg); return -1; } resv_msg_ptr->start_time = t; } else if (strncasecmp(tag, "EndTime", MAX(taglen, 1)) == 0) { time_t t = parse_time(val, 0); if (errno == ESLURM_INVALID_TIME_VALUE) { exit_code = 1; error("Invalid end time %s. %s", argv[i],msg); return -1; } resv_msg_ptr->end_time = t; } else if (strncasecmp(tag, "Duration", MAX(taglen, 1)) == 0) { /* -1 == INFINITE, -2 == error, -3 == not set */ duration = time_str2mins(val); if (duration < 0 && duration != INFINITE) { exit_code = 1; error("Invalid duration %s. %s", argv[i],msg); return -1; } resv_msg_ptr->duration = (uint32_t)duration; } else if (strncasecmp(tag, "Flags", MAX(taglen, 2)) == 0) { uint32_t f; if (plus_minus) { char *tmp = _process_plus_minus(plus_minus, val); f = parse_resv_flags(tmp, msg); xfree(tmp); } else { f = parse_resv_flags(val, msg); } if (f == 0xffffffff) { return -1; } else { resv_msg_ptr->flags = f; } } else if (strncasecmp(tag, "NodeCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "NodeCount", MAX(taglen,5)) == 0) { char *endptr = NULL, *node_cnt, *tok, *ptrptr = NULL; int node_inx = 0; node_cnt = xstrdup(val); tok = strtok_r(node_cnt, ",", &ptrptr); while (tok) { xrealloc(resv_msg_ptr->node_cnt, sizeof(uint32_t) * (node_inx + 2)); resv_msg_ptr->node_cnt[node_inx] = strtol(tok, &endptr, 10); if ((endptr != NULL) && ((endptr[0] == 'k') || (endptr[0] == 'K'))) { resv_msg_ptr->node_cnt[node_inx] *= 1024; } else if ((endptr != NULL) && ((endptr[0] == 'm') || (endptr[0] == 'M'))) { resv_msg_ptr->node_cnt[node_inx] *= 1024 * 1024; } else if ((endptr == NULL) || (endptr[0] != '\0') || (tok[0] == '\0')) { exit_code = 1; error("Invalid node count %s. %s", argv[i], msg); xfree(node_cnt); return -1; } node_inx++; tok = strtok_r(NULL, ",", &ptrptr); } xfree(node_cnt); } else if (strncasecmp(tag, "CoreCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "CoreCount", MAX(taglen,5)) == 0 || strncasecmp(tag, "CPUCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "CPUCount", MAX(taglen,5)) == 0) { char *endptr = NULL, *core_cnt, *tok, *ptrptr = NULL; char *type; int node_inx = 0; type = slurm_get_select_type(); if (strcasestr(type, "cray")) { int param; param = slurm_get_select_type_param(); if (! (param & CR_OTHER_CONS_RES)) { error("CoreCnt or CPUCnt is only " "suported when " "SelectTypeParameters " "includes OTHER_CONS_RES"); xfree(type); return -1; } } else { if (strcasestr(type, "cons_res") == NULL) { error("CoreCnt or CPUCnt is only " "suported when " "SelectType includes " "select/cons_res"); xfree(type); return -1; } } xfree(type); core_cnt = xstrdup(val); tok = strtok_r(core_cnt, ",", &ptrptr); while (tok) { xrealloc(resv_msg_ptr->core_cnt, sizeof(uint32_t) * (node_inx + 2)); resv_msg_ptr->core_cnt[node_inx] = strtol(tok, &endptr, 10); if ((endptr == NULL) || (endptr[0] != '\0') || (tok[0] == '\0')) { exit_code = 1; error("Invalid core count %s. %s", argv[i], msg); xfree(core_cnt); return -1; } node_inx++; tok = strtok_r(NULL, ",", &ptrptr); } xfree(core_cnt); } else if (strncasecmp(tag, "Nodes", MAX(taglen, 5)) == 0) { resv_msg_ptr->node_list = val; } else if (strncasecmp(tag, "Features", MAX(taglen, 2)) == 0) { resv_msg_ptr->features = val; } else if (strncasecmp(tag, "Licenses", MAX(taglen, 2)) == 0) { resv_msg_ptr->licenses = val; } else if (strncasecmp(tag, "PartitionName", MAX(taglen, 1)) == 0) { resv_msg_ptr->partition = val; } else if (strncasecmp(tag, "Users", MAX(taglen, 1)) == 0) { if (plus_minus) { resv_msg_ptr->users = _process_plus_minus(plus_minus, val); *free_user_str = 1; } else { resv_msg_ptr->users = val; } } else if (strncasecmp(tag, "Watts", MAX(taglen, 1)) == 0) { if (parse_uint32(val, &(resv_msg_ptr->resv_watts))) { error("Invalid Watts value: %s", val); return -1; } } else if (strncasecmp(tag, "res", 3) == 0) { continue; } else { exit_code = 1; error("Unknown parameter %s. %s", argv[i], msg); return -1; } } return 0; }