/* Get the Burst buffer information */ extern int get_new_info_bb(burst_buffer_info_msg_t **info_ptr, int force) { static burst_buffer_info_msg_t *new_bb_ptr = NULL; int error_code = SLURM_NO_CHANGE_IN_DATA; time_t now = time(NULL); static time_t last; static bool changed = 0; if (g_bb_info_ptr && !force && ((now - last) < working_sview_config.refresh_delay)) { if (*info_ptr != g_bb_info_ptr) error_code = SLURM_SUCCESS; *info_ptr = g_bb_info_ptr; if (changed) error_code = SLURM_SUCCESS; goto end_it; } last = now; if (g_bb_info_ptr) { error_code = slurm_load_burst_buffer_info(&new_bb_ptr); if (error_code == SLURM_SUCCESS) { slurm_free_burst_buffer_info_msg(g_bb_info_ptr); changed = 1; } else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) { error_code = SLURM_NO_CHANGE_IN_DATA; new_bb_ptr = g_bb_info_ptr; changed = 0; } } else { new_bb_ptr = NULL; error_code = slurm_load_burst_buffer_info(&new_bb_ptr); changed = 1; } g_bb_info_ptr = new_bb_ptr; if (g_bb_info_ptr && (*info_ptr != g_bb_info_ptr)) error_code = SLURM_SUCCESS; *info_ptr = g_bb_info_ptr; end_it: return error_code; }
/* * scontrol_print_burst_buffer - print all burst_buffer information to stdout */ extern void scontrol_print_burst_buffer(void) { int error_code, i; burst_buffer_info_msg_t *burst_buffer_info_ptr = NULL; burst_buffer_info_t *burst_buffer_ptr = NULL; error_code = slurm_load_burst_buffer_info(&burst_buffer_info_ptr); if (error_code) { exit_code = 1; if (quiet_flag != 1) slurm_perror ("slurm_load_burst_buffer error"); return; } burst_buffer_ptr = burst_buffer_info_ptr->burst_buffer_array; for (i = 0; i < burst_buffer_info_ptr->record_count; i++) { slurm_print_burst_buffer_record(stdout, &burst_buffer_ptr[i], one_liner); } slurm_free_burst_buffer_info_msg(burst_buffer_info_ptr); }
/* Test if a job can be allocated a burst buffer. * This may preempt currently active stage-in for higher priority jobs. * * RET 0: Job can be started now * 1: Job exceeds configured limits, continue testing with next job * 2: Job needs more resources than currently available can not start, * skip all remaining jobs */ static int _test_size_limit(struct job_record *job_ptr, uint64_t add_space) { burst_buffer_info_msg_t *resv_bb; struct preempt_bb_recs *preempt_ptr = NULL; List preempt_list; ListIterator preempt_iter; uint64_t resv_space = 0; int add_total_space_needed = 0, add_user_space_needed = 0; int add_total_space_avail = 0, add_user_space_avail = 0; time_t now = time(NULL), when; bb_alloc_t *bb_ptr = NULL; int i; char jobid_buf[32]; if (job_ptr->start_time <= now) when = now; else when = job_ptr->start_time; resv_bb = job_test_bb_resv(job_ptr, when); if (resv_bb) { burst_buffer_info_t *resv_bb_ptr; for (i = 0, resv_bb_ptr = resv_bb->burst_buffer_array; i < resv_bb->record_count; i++, resv_bb_ptr++) { if (resv_bb_ptr->name && strcmp(resv_bb_ptr->name, bb_state.name)) continue; resv_bb_ptr->used_space = bb_granularity(resv_bb_ptr->used_space, bb_state.bb_config.granularity); resv_space += resv_bb_ptr->used_space; } slurm_free_burst_buffer_info_msg(resv_bb); } add_total_space_needed = bb_state.used_space + add_space + resv_space - bb_state.total_space; if ((add_total_space_needed <= 0) && (add_user_space_needed <= 0)) return 0; /* Identify candidate burst buffers to revoke for higher priority job */ preempt_list = list_create(bb_job_queue_del); for (i = 0; i < BB_HASH_SIZE; i++) { bb_ptr = bb_state.bb_ahash[i]; while (bb_ptr) { if (bb_ptr->job_id && (bb_ptr->use_time > now) && (bb_ptr->use_time > job_ptr->start_time)) { preempt_ptr = xmalloc(sizeof( struct preempt_bb_recs)); preempt_ptr->bb_ptr = bb_ptr; preempt_ptr->job_id = bb_ptr->job_id; preempt_ptr->size = bb_ptr->size; preempt_ptr->use_time = bb_ptr->use_time; preempt_ptr->user_id = bb_ptr->user_id; list_push(preempt_list, preempt_ptr); add_total_space_avail += bb_ptr->size; if (bb_ptr->user_id == job_ptr->user_id) add_user_space_avail += bb_ptr->size; } bb_ptr = bb_ptr->next; } } if ((add_total_space_avail >= add_total_space_needed) && (add_user_space_avail >= add_user_space_needed)) { list_sort(preempt_list, bb_preempt_queue_sort); preempt_iter = list_iterator_create(preempt_list); while ((preempt_ptr = list_next(preempt_iter)) && (add_total_space_needed || add_user_space_needed)) { if (add_user_space_needed && (preempt_ptr->user_id == job_ptr->user_id)) { _stop_stage_in(preempt_ptr->job_id); preempt_ptr->bb_ptr->cancelled = true; preempt_ptr->bb_ptr->end_time = 0; if (bb_state.bb_config.debug_flag) { info("%s: %s: Preempting stage-in of " "job %u for %s", plugin_type, __func__, preempt_ptr->job_id, jobid2fmt(job_ptr, jobid_buf, sizeof(jobid_buf))); } add_user_space_needed -= preempt_ptr->size; add_total_space_needed -= preempt_ptr->size; } if ((add_total_space_needed > add_user_space_needed) && (preempt_ptr->user_id != job_ptr->user_id)) { _stop_stage_in(preempt_ptr->job_id); preempt_ptr->bb_ptr->cancelled = true; preempt_ptr->bb_ptr->end_time = 0; if (bb_state.bb_config.debug_flag) { info("%s: %s: Preempting stage-in of " "job %u for %s", plugin_type, __func__, preempt_ptr->job_id, jobid2fmt(job_ptr, jobid_buf, sizeof(jobid_buf))); } add_total_space_needed -= preempt_ptr->size; } } list_iterator_destroy(preempt_iter); } FREE_NULL_LIST(preempt_list); return 2; }
extern void _change_cluster_main(GtkComboBox *combo, gpointer extra) { GtkTreeModel *model; display_data_t *display_data; GtkTreeIter iter; slurmdb_cluster_rec_t *cluster_rec = NULL; char *tmp, *ui_description; GError *error = NULL; GtkWidget *node_tab = NULL; int rc; bool got_grid = 0; if (!gtk_combo_box_get_active_iter(combo, &iter)) { g_print("nothing selected\n"); return; } model = gtk_combo_box_get_model(combo); if (!model) { g_print("nothing selected\n"); return; } gtk_tree_model_get(model, &iter, 1, &cluster_rec, -1); if (!cluster_rec) { g_print("no cluster_rec pointer here!"); return; } /* From testing it doesn't appear you can get here without a legitimate change, so there isn't a need to check if we are going back to the same cluster we were just at. */ /* if (working_cluster_rec) { */ /* if (!xstrcmp(cluster_rec->name, working_cluster_rec->name)) */ /* return; */ /* } */ /* free old info under last cluster */ slurm_free_block_info_msg(g_block_info_ptr); g_block_info_ptr = NULL; slurm_free_front_end_info_msg(g_front_end_info_ptr); g_front_end_info_ptr = NULL; slurm_free_burst_buffer_info_msg(g_bb_info_ptr); g_bb_info_ptr = NULL; slurm_free_job_info_msg(g_job_info_ptr); g_job_info_ptr = NULL; slurm_free_node_info_msg(g_node_info_ptr); g_node_info_ptr = NULL; slurm_free_partition_info_msg(g_part_info_ptr); g_part_info_ptr = NULL; slurm_free_reservation_info_msg(g_resv_info_ptr); g_resv_info_ptr = NULL; slurm_free_ctl_conf(g_ctl_info_ptr); g_ctl_info_ptr = NULL; slurm_free_job_step_info_response_msg(g_step_info_ptr); g_step_info_ptr = NULL; slurm_free_topo_info_msg(g_topo_info_msg_ptr); g_topo_info_msg_ptr = NULL; /* set up working_cluster_rec */ if (cluster_dims > 1) { /* reset from a multi-dim cluster */ working_sview_config.grid_x_width = default_sview_config.grid_x_width; working_sview_config.grid_hori = default_sview_config.grid_hori; working_sview_config.grid_vert = default_sview_config.grid_vert; } gtk_table_set_col_spacings(main_grid_table, 0); gtk_table_set_row_spacings(main_grid_table, 0); if (!orig_cluster_name) orig_cluster_name = slurm_get_cluster_name(); if (!xstrcmp(cluster_rec->name, orig_cluster_name)) working_cluster_rec = NULL; else working_cluster_rec = cluster_rec; cluster_dims = slurmdb_setup_cluster_dims(); cluster_flags = slurmdb_setup_cluster_flags(); display_data = main_display_data; while (display_data++) { if (display_data->id == -1) break; if (cluster_flags & CLUSTER_FLAG_BG) { switch(display_data->id) { case BLOCK_PAGE: display_data->show = true; break; case NODE_PAGE: display_data->name = "Midplanes"; break; default: break; } } else { switch(display_data->id) { case BLOCK_PAGE: display_data->show = false; break; case NODE_PAGE: display_data->name = "Nodes"; break; default: break; } } } /* set up menu */ ui_description = _get_ui_description(); gtk_ui_manager_remove_ui(g_ui_manager, g_menu_id); if (!(g_menu_id = gtk_ui_manager_add_ui_from_string( g_ui_manager, ui_description, -1, &error))) { xfree(ui_description); g_error("building menus failed: %s", error->message); g_error_free (error); exit (0); } xfree(ui_description); /* make changes for each object */ cluster_change_block(); cluster_change_front_end(); cluster_change_resv(); cluster_change_part(); cluster_change_job(); cluster_change_node(); cluster_change_bb(); /* destroy old stuff */ if (grid_button_list) { FREE_NULL_LIST(grid_button_list); got_grid = 1; } select_g_ba_fini(); /* sorry popups can't survive a cluster change */ if (popup_list) list_flush(popup_list); if (signal_params_list) list_flush(signal_params_list); if (signal_params_list) list_flush(signal_params_list); if (g_switch_nodes_maps) free_switch_nodes_maps(g_switch_nodes_maps); /* change the node tab name if needed */ node_tab = gtk_notebook_get_nth_page( GTK_NOTEBOOK(main_notebook), NODE_PAGE); node_tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(main_notebook), node_tab); #ifdef GTK2_USE_GET_FOCUS /* ok, now we have a table which we have set up to contain an * event_box which contains the label we are interested. We * setup this label to be the focus child of the table, so all * we have to do is grab that and we are set. */ node_tab = gtk_container_get_focus_child(GTK_CONTAINER(node_tab)); #else /* See above comment. Since gtk_container_get_focus_child * doesn't exist yet we will just traverse the children until * we find the label widget and then break. */ { int i = 0; GList *children = gtk_container_get_children( GTK_CONTAINER(node_tab)); while ((node_tab = g_list_nth_data(children, i++))) { int j = 0; GList *children2 = gtk_container_get_children( GTK_CONTAINER(node_tab)); while ((node_tab = g_list_nth_data(children2, j++))) { if (GTK_IS_LABEL(node_tab)) break; } g_list_free(children2); if (node_tab) break; } g_list_free(children); } #endif if (node_tab) gtk_label_set_text(GTK_LABEL(node_tab), main_display_data[NODE_PAGE].name); /* The name in the visible tabs is easier since it is really just a button with a label on it. */ if (default_sview_config.page_check_widget[NODE_PAGE]) { gtk_button_set_label(GTK_BUTTON(default_sview_config. page_check_widget[NODE_PAGE]), main_display_data[NODE_PAGE].name); } /* reinit */ rc = get_system_stats(main_grid_table); if (rc == SLURM_SUCCESS) { /* It turns out if we didn't have the grid (cluster not responding) before the new grid doesn't get set up correctly. Redoing the system_stats fixes it. There is probably a better way of doing this, but it doesn't happen very often and isn't that bad to handle every once in a while. */ if (!got_grid) { /* I know we just did this before, but it needs to be done again here. */ FREE_NULL_LIST(grid_button_list); get_system_stats(main_grid_table); } refresh_main(NULL, NULL); } tmp = g_strdup_printf("Cluster changed to %s", cluster_rec->name); display_edit_note(tmp); g_free(tmp); }