extern int parse_image(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_options_t image_options[] = { {(char *)"GROUPS", S_P_STRING}, {NULL} }; s_p_hashtbl_t *tbl = NULL; char *tmp = NULL; image_t *n = NULL; image_group_t *image_group = NULL; int i = 0, j = 0; tbl = s_p_hashtbl_create(image_options); s_p_parse_line(tbl, *leftover, leftover); n = (image_t *)xmalloc(sizeof(image_t)); n->name = xstrdup(value); n->def = false; n->groups = list_create(destroy_image_group_list); s_p_get_string(&tmp, "Groups", tbl); if (tmp) { for(i=0; i<(int)strlen(tmp); i++) { if ((tmp[i] == ':') || (tmp[i] == ',')) { image_group = (image_group_t *) xmalloc(sizeof(image_group_t)); image_group->name = (char *)xmalloc(i-j+2); snprintf(image_group->name, (i-j)+1, "%s", tmp+j); gid_from_string (image_group->name, &image_group->gid); list_append(n->groups, image_group); j=i; j++; } } if (j != i) { image_group = (image_group_t *) xmalloc(sizeof(image_group_t)); image_group->name = (char *)xmalloc(i-j+2); snprintf(image_group->name, (i-j)+1, "%s", tmp+j); if (gid_from_string (image_group->name, &image_group->gid) < 0) fatal("Invalid bluegene.conf parameter " "Groups=%s", image_group->name); list_append(n->groups, image_group); } xfree(tmp); } s_p_hashtbl_destroy(tbl); *dest = (void *)n; return 1; }
static int _parse_switches(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_hashtbl_t *tbl; slurm_conf_switches_t *s; static s_p_options_t _switch_options[] = { {"LinkSpeed", S_P_UINT32}, {"Nodes", S_P_STRING}, {"Switches", S_P_STRING}, {NULL} }; tbl = s_p_hashtbl_create(_switch_options); s_p_parse_line(tbl, *leftover, leftover); s = xmalloc(sizeof(slurm_conf_switches_t)); s->switch_name = xstrdup(value); if (!s_p_get_uint32(&s->link_speed, "LinkSpeed", tbl)) s->link_speed = 1; s_p_get_string(&s->nodes, "Nodes", tbl); s_p_get_string(&s->switches, "Switches", tbl); s_p_hashtbl_destroy(tbl); if (s->nodes && s->switches) { error("switch %s has both child switches and nodes", s->switch_name); _destroy_switches(s); return -1; } if (!s->nodes && !s->switches) { error("switch %s has neither child switches nor nodes", s->switch_name); _destroy_switches(s); return -1; } *dest = (void *)s; return 1; }
/* Determine the current actual burst buffer state. * Run the program "get_sys_state" and parse stdout for details. */ static void _load_state(void) { static uint32_t last_total_space = 0; char *save_ptr = NULL, *tok, *leftover = NULL, *resp, *tmp = NULL; char *script_args[3] = { NULL, "get_sys", NULL }; s_p_hashtbl_t *state_hashtbl = NULL; static s_p_options_t state_options[] = { {"ENOENT", S_P_STRING}, {"UserID", S_P_ARRAY, _parse_job_info, _destroy_job_info}, {"TotalSize", S_P_STRING}, {NULL} }; tok = strrchr(get_sys_state, '/'); if (tok) script_args[0] = tok + 1; else script_args[0] = get_sys_state; resp = _run_script("GetSysState", get_sys_state, script_args, 10); if (resp == NULL) return; state_hashtbl = s_p_hashtbl_create(state_options); tok = strtok_r(resp, "\n", &save_ptr); while (tok) { s_p_parse_line(state_hashtbl, tok, &leftover); tok = strtok_r(NULL, "\n", &save_ptr); } if (s_p_get_string(&tmp, "TotalSize", state_hashtbl)) { total_space = _get_size_num(tmp); xfree(tmp); } else { error("%s: GetSysState failed to respond with TotalSize", plugin_type); } s_p_hashtbl_destroy(state_hashtbl); if (debug_flag && (total_space != last_total_space)) info("%s: total_space:%u", __func__, total_space); last_total_space = total_space; }
/* * Determine the current actual burst buffer state. * Run the program "get_sys_state" and parse stdout for details. * job_id IN - specific job to get information about, or 0 for all jobs */ static void _load_state(uint32_t job_id) { static uint64_t last_total_space = 0; char *save_ptr = NULL, *tok, *leftover = NULL, *resp, *tmp = NULL; char *script_args[4], job_id_str[32]; s_p_hashtbl_t *state_hashtbl = NULL; static s_p_options_t state_options[] = { {"ENOENT", S_P_STRING}, {"UserID", S_P_ARRAY, _parse_job_info, _destroy_job_info}, {"TotalSize", S_P_STRING}, {NULL} }; int status = 0; DEF_TIMERS; if (!bb_state.bb_config.get_sys_state) return; bb_state.last_load_time = time(NULL); tok = strrchr(bb_state.bb_config.get_sys_state, '/'); if (tok) script_args[0] = tok + 1; else script_args[0] = bb_state.bb_config.get_sys_state; if (job_id) { script_args[1] = "get_job"; snprintf(job_id_str, sizeof(job_id_str), "%u", job_id); script_args[3] = NULL; } else { script_args[1] = "get_sys"; script_args[2] = NULL; } START_TIMER; resp = bb_run_script("GetSysState", bb_state.bb_config.get_sys_state, script_args, 2000, &status); if (resp == NULL) return; END_TIMER; if (DELTA_TIMER > 200000) /* 0.2 secs */ info("%s: GetSysState ran for %s", __func__, TIME_STR); else if (bb_state.bb_config.debug_flag) debug("%s: GetSysState ran for %s", __func__, TIME_STR); state_hashtbl = s_p_hashtbl_create(state_options); tok = strtok_r(resp, "\n", &save_ptr); while (tok) { s_p_parse_line(state_hashtbl, tok, &leftover); tok = strtok_r(NULL, "\n", &save_ptr); } if (s_p_get_string(&tmp, "TotalSize", state_hashtbl)) { bb_state.total_space = bb_get_size_num(tmp, bb_state.bb_config.granularity); xfree(tmp); if (bb_state.bb_config.debug_flag && (bb_state.total_space != last_total_space)) { info("%s: total_space:%"PRIu64"", __func__, bb_state.total_space); } last_total_space = bb_state.total_space; } else if (job_id == 0) { error("%s: GetSysState failed to respond with TotalSize", plugin_type); } s_p_hashtbl_destroy(state_hashtbl); xfree(resp); }
static int _parse_job_info(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_hashtbl_t *job_tbl; char *name = NULL, *tmp = NULL, local_name[64] = ""; uint64_t size = 0; uint32_t job_id = 0, user_id = 0; uint16_t state = 0; bb_alloc_t *bb_ptr; struct job_record *job_ptr = NULL; bb_job_t *bb_spec; static s_p_options_t _job_options[] = { {"JobID",S_P_STRING}, {"Name", S_P_STRING}, {"Size", S_P_STRING}, {"State", S_P_STRING}, {NULL} }; *dest = NULL; user_id = strtol(value, NULL, 10); job_tbl = s_p_hashtbl_create(_job_options); s_p_parse_line(job_tbl, *leftover, leftover); if (s_p_get_string(&tmp, "JobID", job_tbl)) { job_id = strtol(tmp, NULL, 10); xfree(tmp); } if (s_p_get_string(&name, "Name", job_tbl)) { snprintf(local_name, sizeof(local_name), "%s", name); xfree(name); } if (s_p_get_string(&tmp, "Size", job_tbl)) { size = bb_get_size_num(tmp, bb_state.bb_config.granularity); xfree(tmp); } if (s_p_get_string(&tmp, "State", job_tbl)) { state = bb_state_num(tmp); xfree(tmp); } s_p_hashtbl_destroy(job_tbl); #if 0 info("%s: JobID:%u Name:%s Size:%"PRIu64" State:%u UserID:%u", __func__, job_id, local_name, size, state, user_id); #endif if (job_id) { job_ptr = find_job_record(job_id); if (!job_ptr && (state == BB_STATE_STAGED_OUT)) { struct job_record job_rec; job_rec.job_id = job_id; job_rec.user_id = user_id; bb_ptr = bb_find_alloc_rec(&bb_state, &job_rec); _stop_stage_out(job_id); /* Purge buffer */ if (bb_ptr) { bb_ptr->cancelled = true; bb_ptr->end_time = 0; } else { /* Slurm knows nothing about this job, * may be result of slurmctld cold start */ error("%s: Vestigial buffer for purged job %u", plugin_type, job_id); } return SLURM_SUCCESS; } else if (!job_ptr && ((state == BB_STATE_STAGING_IN) || (state == BB_STATE_STAGED_IN))) { struct job_record job_rec; job_rec.job_id = job_id; job_rec.user_id = user_id; bb_ptr = bb_find_alloc_rec(&bb_state, &job_rec); _stop_stage_in(job_id); /* Purge buffer */ if (bb_ptr) { bb_ptr->cancelled = true; bb_ptr->end_time = 0; } else { /* Slurm knows nothing about this job, * may be result of slurmctld cold start */ error("%s: Vestigial buffer for purged job %u", plugin_type, job_id); } return SLURM_SUCCESS; } else if (!job_ptr) { error("%s: Vestigial buffer for job ID %u. " "Clear manually", plugin_type, job_id); } snprintf(local_name, sizeof(local_name), "VestigialJob%u", job_id); } if (job_ptr) { bb_ptr = bb_find_alloc_rec(&bb_state, job_ptr); if (bb_ptr == NULL) { bb_spec = xmalloc(sizeof(bb_job_t)); bb_spec->total_size = _get_bb_size(job_ptr); bb_ptr = bb_alloc_job_rec(&bb_state, job_ptr, bb_spec); xfree(bb_spec); bb_ptr->state = state; /* bb_ptr->state_time set in bb_alloc_job_rec() */ } } else { if ((bb_ptr = _find_bb_name_rec(local_name, user_id)) == NULL) { bb_ptr = bb_alloc_name_rec(&bb_state, local_name, user_id); bb_ptr->size = size; bb_ptr->state = state; //FIXME: VESTIGIAL: Use bb_limit_add // bb_add_user_load(bb_ptr, &bb_state); return SLURM_SUCCESS; } } bb_ptr->seen_time = time(NULL); /* used to purge defunct recs */ /* UserID set to 0 on some failure modes */ if ((bb_ptr->user_id != user_id) && (user_id != 0)) { error("%s: User ID mismatch (%u != %u). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_ptr->user_id, user_id, bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); } if ((bb_ptr->state == BB_STATE_RUNNING) && (state == BB_STATE_STAGED_IN)) state = BB_STATE_RUNNING; /* More precise state info */ if (bb_ptr->state != state) { /* State is subject to real-time changes */ debug("%s: State changed (%s to %s). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_state_string(bb_ptr->state), bb_state_string(state), bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); bb_ptr->state = state; bb_ptr->state_time = time(NULL); if (bb_ptr->state == BB_STATE_STAGED_OUT) { if (bb_ptr->size != 0) { //FIXME: VESTIGIAL: Use bb_limit_rem // bb_remove_user_load(bb_ptr, &bb_state); bb_ptr->size = 0; } } if (bb_ptr->state == BB_STATE_STAGED_IN) queue_job_scheduler(); } if ((bb_ptr->state != BB_STATE_STAGED_OUT) && (bb_ptr->size != size)) { //FIXME: VESTIGIAL: Use bb_limit_rem // bb_remove_user_load(bb_ptr, &bb_state); if (size != 0) { error("%s: Size mismatch (%"PRIu64" != %"PRIu64"). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_ptr->size, size, bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); } bb_ptr->size = MAX(bb_ptr->size, size); //FIXME: VESTIGIAL: Use bb_limit_add // bb_add_user_load(bb_ptr, &bb_state); } return SLURM_SUCCESS; }
extern int parse_blockreq(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_options_t block_options[] = { {"Type", S_P_STRING}, {"32CNBlocks", S_P_UINT16}, {"128CNBlocks", S_P_UINT16}, #ifdef HAVE_BGL {"Nodecards", S_P_UINT16}, {"Quarters", S_P_UINT16}, {"BlrtsImage", S_P_STRING}, {"LinuxImage", S_P_STRING}, {"RamDiskImage", S_P_STRING}, #else {"16CNBlocks", S_P_UINT16}, {"64CNBlocks", S_P_UINT16}, {"256CNBlocks", S_P_UINT16}, {"CnloadImage", S_P_STRING}, {"IoloadImage", S_P_STRING}, #endif {"MloaderImage", S_P_STRING}, {NULL} }; s_p_hashtbl_t *tbl; char *tmp = NULL; select_ba_request_t *n = NULL; hostlist_t hl = NULL; tbl = s_p_hashtbl_create(block_options); s_p_parse_line(tbl, *leftover, leftover); if (!value) { return 0; } n = xmalloc(sizeof(select_ba_request_t)); hl = hostlist_create(value); n->save_name = hostlist_ranged_string_xmalloc(hl); hostlist_destroy(hl); #ifdef HAVE_BGL s_p_get_string(&n->blrtsimage, "BlrtsImage", tbl); s_p_get_string(&n->linuximage, "LinuxImage", tbl); s_p_get_string(&n->ramdiskimage, "RamDiskImage", tbl); #else s_p_get_string(&n->linuximage, "CnloadImage", tbl); s_p_get_string(&n->ramdiskimage, "IoloadImage", tbl); #endif s_p_get_string(&n->mloaderimage, "MloaderImage", tbl); s_p_get_string(&tmp, "Type", tbl); if (!tmp || !strcasecmp(tmp,"TORUS")) n->conn_type[0] = SELECT_TORUS; else if (!strcasecmp(tmp,"MESH")) n->conn_type[0] = SELECT_MESH; else n->conn_type[0] = SELECT_SMALL; xfree(tmp); if (!s_p_get_uint16(&n->small32, "32CNBlocks", tbl)) { #ifdef HAVE_BGL s_p_get_uint16(&n->small32, "Nodecards", tbl); #else ; #endif } if (!s_p_get_uint16(&n->small128, "128CNBlocks", tbl)) { #ifdef HAVE_BGL s_p_get_uint16(&n->small128, "Quarters", tbl); #else ; #endif } #ifndef HAVE_BGL s_p_get_uint16(&n->small16, "16CNBlocks", tbl); s_p_get_uint16(&n->small64, "64CNBlocks", tbl); s_p_get_uint16(&n->small256, "256CNBlocks", tbl); #endif s_p_hashtbl_destroy(tbl); *dest = (void *)n; return 1; }
extern int parse_blockreq(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_options_t block_options[] = { {"Type", S_P_STRING}, {"32CNBlocks", S_P_UINT16}, {"128CNBlocks", S_P_UINT16}, #ifdef HAVE_BGL {"Nodecards", S_P_UINT16}, {"Quarters", S_P_UINT16}, {"BlrtsImage", S_P_STRING}, {"LinuxImage", S_P_STRING}, {"RamDiskImage", S_P_STRING}, #else #ifdef HAVE_BGP {"16CNBlocks", S_P_UINT16}, {"CnloadImage", S_P_STRING}, {"IoloadImage", S_P_STRING}, #endif {"64CNBlocks", S_P_UINT16}, {"256CNBlocks", S_P_UINT16}, #endif {"MloaderImage", S_P_STRING}, {NULL} }; s_p_hashtbl_t *tbl; char *tmp = NULL; select_ba_request_t *n = NULL; hostlist_t hl = NULL; tbl = s_p_hashtbl_create(block_options); s_p_parse_line(tbl, *leftover, leftover); if (!value) { return 0; } n = xmalloc(sizeof(select_ba_request_t)); hl = hostlist_create(value); n->save_name = hostlist_ranged_string_xmalloc(hl); hostlist_destroy(hl); #ifdef HAVE_BGL s_p_get_string(&n->blrtsimage, "BlrtsImage", tbl); s_p_get_string(&n->linuximage, "LinuxImage", tbl); s_p_get_string(&n->ramdiskimage, "RamDiskImage", tbl); #elif defined HAVE_BGP s_p_get_string(&n->linuximage, "CnloadImage", tbl); s_p_get_string(&n->ramdiskimage, "IoloadImage", tbl); #endif s_p_get_string(&n->mloaderimage, "MloaderImage", tbl); s_p_get_string(&tmp, "Type", tbl); if (tmp) { verify_conn_type(tmp, n->conn_type); xfree(tmp); } if (!s_p_get_uint16(&n->small32, "32CNBlocks", tbl)) { #ifdef HAVE_BGL s_p_get_uint16(&n->small32, "Nodecards", tbl); #else ; #endif } if (!s_p_get_uint16(&n->small128, "128CNBlocks", tbl)) { #ifdef HAVE_BGL s_p_get_uint16(&n->small128, "Quarters", tbl); #else ; #endif } #ifndef HAVE_BGL #ifdef HAVE_BGP s_p_get_uint16(&n->small16, "16CNBlocks", tbl); #endif s_p_get_uint16(&n->small64, "64CNBlocks", tbl); s_p_get_uint16(&n->small256, "256CNBlocks", tbl); #endif if (n->small16 || n->small32 || n->small64 || n->small128 || n->small256) { if (n->conn_type[0] < SELECT_SMALL) { error("Block def on midplane(s) %s is " "asking for small blocks but given " "TYPE=%s, setting it to Small", n->save_name, conn_type_string(n->conn_type[0])); n->conn_type[0] = SELECT_SMALL; } } else { if (n->conn_type[0] == (uint16_t)NO_VAL) { n->conn_type[0] = bg_conf->default_conn_type[0]; } else if (n->conn_type[0] >= SELECT_SMALL) { error("Block def on midplane(s) %s is given " "TYPE=%s but isn't asking for any small " "blocks. Giving it %s.", n->save_name, conn_type_string(n->conn_type[0]), conn_type_string( bg_conf->default_conn_type[0])); n->conn_type[0] = bg_conf->default_conn_type[0]; } #ifndef HAVE_BG_L_P int i; for (i=1; i<SYSTEM_DIMENSIONS; i++) { if (n->conn_type[i] == (uint16_t)NO_VAL) n->conn_type[i] = bg_conf->default_conn_type[i]; else if (n->conn_type[i] >= SELECT_SMALL) { error("Block def on midplane(s) %s dim %d " "is given TYPE=%s but isn't asking " "for any small blocks. Giving it %s.", n->save_name, i, conn_type_string(n->conn_type[i]), conn_type_string( bg_conf->default_conn_type[i])); n->conn_type[i] = bg_conf->default_conn_type[i]; } } #endif } s_p_hashtbl_destroy(tbl); *dest = (void *)n; return 1; }
static int _parse_job_info(void **dest, slurm_parser_enum_t type, const char *key, const char *value, const char *line, char **leftover) { s_p_hashtbl_t *job_tbl; char *name = NULL, *tmp = NULL, tmp_name[64]; uint32_t job_id = 0, size = 0, user_id = 0; uint16_t state = 0; bb_alloc_t *bb_ptr; struct job_record *job_ptr = NULL; static s_p_options_t _job_options[] = { {"JobID",S_P_STRING}, {"Name", S_P_STRING}, {"Size", S_P_STRING}, {"State", S_P_STRING}, {NULL} }; *dest = NULL; user_id = atoi(value); job_tbl = s_p_hashtbl_create(_job_options); s_p_parse_line(job_tbl, *leftover, leftover); if (s_p_get_string(&tmp, "JobID", job_tbl)) job_id = atoi(tmp); s_p_get_string(&name, "Name", job_tbl); if (s_p_get_string(&tmp, "Size", job_tbl)) size = _get_size_num(tmp); if (s_p_get_string(&tmp, "State", job_tbl)) state = bb_state_num(tmp); #if 1 info("%s: JobID:%u Name:%s Size:%u State:%u UserID:%u", __func__, job_id, name, size, state, user_id); #endif if (job_id) { job_ptr = find_job_record(job_id); if (!job_ptr) { error("%s: Vestigial buffer for job ID %u. " "Clear manually", plugin_type, job_id); } snprintf(tmp_name, sizeof(tmp_name), "VestigialJob%u", job_id); job_id = 0; name = tmp_name; } if (job_ptr) { if ((bb_ptr = _find_bb_job_rec(job_ptr)) == NULL) { bb_ptr = _alloc_bb_job_rec(job_ptr); bb_ptr->state = state; } } else { if ((bb_ptr = _find_bb_name_rec(name, user_id)) == NULL) { bb_ptr = _alloc_bb_name_rec(name, user_id); bb_ptr->size = size; bb_ptr->state = state; return SLURM_SUCCESS; } } if (bb_ptr->user_id != user_id) { error("%s: User ID mismatch (%u != %u). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_ptr->user_id, user_id, bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); } if (bb_ptr->size != size) { error("%s: Size mismatch (%u != %u). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_ptr->size, size, bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); bb_ptr->size = MAX(bb_ptr->size, size); } if (bb_ptr->state != state) { /* State is subject to real-time changes */ debug("%s: State mismatch (%s != %s). " "BB UserID=%u JobID=%u Name=%s", plugin_type, bb_state_string(bb_ptr->state), bb_state_string(state), bb_ptr->user_id, bb_ptr->job_id, bb_ptr->name); } return SLURM_SUCCESS; }