static int _dynamically_request(List block_list, int *blocks_added, select_ba_request_t *request, char *user_req_nodes, uint16_t query_mode) { List list_of_lists = NULL; List temp_list = NULL; List new_blocks = NULL; List job_list = NULL, booted_list = NULL; ListIterator itr = NULL; int rc = SLURM_ERROR; int create_try = 0; if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("going to create %d", request->size); list_of_lists = list_create(NULL); /* If preempt is set and we are checking full system it means we altered the block list so only look at it. */ if (SELECT_IS_PREEMPT_SET(query_mode) && SELECT_IS_CHECK_FULL_SET(query_mode)) { list_append(list_of_lists, block_list); } else if (user_req_nodes) { slurm_mutex_lock(&block_state_mutex); job_list = copy_bg_list(bg_lists->job_running); list_append(list_of_lists, job_list); slurm_mutex_unlock(&block_state_mutex); } else { slurm_mutex_lock(&block_state_mutex); list_append(list_of_lists, block_list); if (list_count(block_list) != list_count(bg_lists->booted)) { booted_list = copy_bg_list(bg_lists->booted); list_append(list_of_lists, booted_list); if (list_count(bg_lists->booted) != list_count(bg_lists->job_running)) { job_list = copy_bg_list(bg_lists->job_running); list_append(list_of_lists, job_list); } } else if (list_count(block_list) != list_count(bg_lists->job_running)) { job_list = copy_bg_list(bg_lists->job_running); list_append(list_of_lists, job_list); } slurm_mutex_unlock(&block_state_mutex); } itr = list_iterator_create(list_of_lists); while ((temp_list = (List)list_next(itr))) { create_try++; /* 1- try empty space 2- we see if we can create one in the unused mps 3- see if we can create one in the non job running mps */ if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("trying with %d", create_try); if ((new_blocks = create_dynamic_block( block_list, request, temp_list, true))) { bg_record_t *bg_record = NULL; while ((bg_record = list_pop(new_blocks))) { if (block_exist_in_list(block_list, bg_record)) destroy_bg_record(bg_record); else if (SELECT_IS_TEST(query_mode) || SELECT_IS_PREEMPT_ON_FULL_TEST( query_mode)) { /* Here we don't really want to create the block if we are testing. The second test here is to make sure If we are able to run here but we just preempted we should wait a bit to make sure the preempted blocks have time to clear out. */ list_append(block_list, bg_record); (*blocks_added) = 1; } else { if (bridge_block_create(bg_record) == SLURM_ERROR) { destroy_bg_record(bg_record); error("_dynamically_request: " "unable to configure " "block"); rc = SLURM_ERROR; break; } list_append(block_list, bg_record); print_bg_record(bg_record); (*blocks_added) = 1; } } list_destroy(new_blocks); if (!*blocks_added) { rc = SLURM_ERROR; continue; } list_sort(block_list, (ListCmpF)bg_record_sort_aval_inc); rc = SLURM_SUCCESS; break; } else if (errno == ESLURM_INTERCONNECT_FAILURE) { rc = SLURM_ERROR; break; } } list_iterator_destroy(itr); if (list_of_lists) list_destroy(list_of_lists); if (job_list) list_destroy(job_list); if (booted_list) list_destroy(booted_list); return rc; }
/* * create_defined_blocks - create the static blocks that will be used * for scheduling, all partitions must be able to be created and booted * at once. * IN - int overlapped, 1 if partitions are to be overlapped, 0 if they are * static. * RET - success of fitting all configurations */ extern int create_defined_blocks(bg_layout_t overlapped, List bg_found_block_list) { int rc = SLURM_SUCCESS; ListIterator itr; bg_record_t *bg_record = NULL; int i; uint16_t geo[SYSTEM_DIMENSIONS]; char temp[256]; struct part_record *part_ptr = NULL; bitstr_t *usable_mp_bitmap = bit_alloc(node_record_count); /* Locks are already in place to protect part_list here */ itr = list_iterator_create(part_list); while ((part_ptr = list_next(itr))) { /* we only want to use mps that are in * partitions */ if (!part_ptr->node_bitmap) { debug4("Partition %s doesn't have any nodes in it.", part_ptr->name); continue; } bit_or(usable_mp_bitmap, part_ptr->node_bitmap); } list_iterator_destroy(itr); if (bit_ffs(usable_mp_bitmap) == -1) { fatal("We don't have any nodes in any partitions. " "Can't create blocks. " "Please check your slurm.conf."); } slurm_mutex_lock(&block_state_mutex); reset_ba_system(false); ba_set_removable_mps(usable_mp_bitmap, 1); if (bg_lists->main) { itr = list_iterator_create(bg_lists->main); while ((bg_record = list_next(itr))) { if (bg_record->mp_count > 0 && !bg_record->full_block && bg_record->cpu_cnt >= bg_conf->cpus_per_mp) { char *name = NULL; char start_char[SYSTEM_DIMENSIONS+1]; char geo_char[SYSTEM_DIMENSIONS+1]; if (overlapped == LAYOUT_OVERLAP) { reset_ba_system(false); ba_set_removable_mps(usable_mp_bitmap, 1); } /* we want the mps that aren't * in this record to mark them as used */ if (ba_set_removable_mps( bg_record->mp_bitmap, 1) != SLURM_SUCCESS) fatal("It doesn't seem we have a " "bitmap for %s", bg_record->bg_block_id); for (i=0; i<SYSTEM_DIMENSIONS; i++) { geo[i] = bg_record->geo[i]; start_char[i] = alpha_num[ bg_record->start[i]]; geo_char[i] = alpha_num[geo[i]]; } start_char[i] = '\0'; geo_char[i] = '\0'; debug2("adding %s %s %s", bg_record->mp_str, start_char, geo_char); if (bg_record->ba_mp_list && list_count(bg_record->ba_mp_list)) { if ((rc = check_and_set_mp_list( bg_record->ba_mp_list)) != SLURM_SUCCESS) { debug2("something happened in " "the load of %s" "Did you use smap to " "make the " "bluegene.conf file?", bg_record->bg_block_id); break; } } else { #ifdef HAVE_BGQ List results = list_create(destroy_ba_mp); #else List results = list_create(NULL); #endif name = set_bg_block( results, bg_record->start, geo, bg_record->conn_type); ba_reset_all_removed_mps(); if (!name) { error("I was unable to " "make the " "requested block."); list_destroy(results); rc = SLURM_ERROR; break; } snprintf(temp, sizeof(temp), "%s%s", bg_conf->slurm_node_prefix, name); xfree(name); if (strcmp(temp, bg_record->mp_str)) { fatal("given list of %s " "but allocated %s, " "your order might be " "wrong in bluegene.conf", bg_record->mp_str, temp); } if (bg_record->ba_mp_list) list_destroy( bg_record->ba_mp_list); #ifdef HAVE_BGQ bg_record->ba_mp_list = results; results = NULL; #else bg_record->ba_mp_list = list_create(destroy_ba_mp); copy_node_path(results, &bg_record->ba_mp_list); list_destroy(results); #endif } } if (!block_exist_in_list( bg_found_block_list, bg_record)) { if (bg_record->full_block) { /* if this is defined we need to remove it since we are going to try to create it later on overlap systems this doesn't matter, but since we don't clear the table on static mode we can't do it here or it just won't work since other wires will be or are already set */ list_remove(itr); continue; } if ((rc = bridge_block_create(bg_record)) != SLURM_SUCCESS) break; print_bg_record(bg_record); } } list_iterator_destroy(itr); if (rc != SLURM_SUCCESS) goto end_it; } else { error("create_defined_blocks: no bg_lists->main 2"); rc = SLURM_ERROR; goto end_it; } slurm_mutex_unlock(&block_state_mutex); create_full_system_block(bg_found_block_list); slurm_mutex_lock(&block_state_mutex); sort_bg_record_inc_size(bg_lists->main); end_it: ba_reset_all_removed_mps(); FREE_NULL_BITMAP(usable_mp_bitmap); slurm_mutex_unlock(&block_state_mutex); #ifdef _PRINT_BLOCKS_AND_EXIT if (bg_lists->main) { itr = list_iterator_create(bg_lists->main); debug("\n\n"); while ((found_record = (bg_record_t *) list_next(itr)) != NULL) { print_bg_record(found_record); } list_iterator_destroy(itr); } else { error("create_defined_blocks: no bg_lists->main 5"); } exit(0); #endif /* _PRINT_BLOCKS_AND_EXIT */ //exit(0); return rc; }