extern int sacctmgr_list_txn(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_txn_cond_t *txn_cond = xmalloc(sizeof(slurmdb_txn_cond_t)); List txn_list = NULL; slurmdb_txn_rec_t *txn = NULL; int i=0; ListIterator itr = NULL; ListIterator itr2 = NULL; int field_count = 0; print_field_t *field = NULL; List format_list = list_create(slurm_destroy_char); List print_fields_list; /* types are of print_field_t */ for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5)) || !strncasecmp (argv[i], "Set", MAX(command_len, 3))) i++; _set_cond(&i, argc, argv, txn_cond, format_list); } if (exit_code) { slurmdb_destroy_txn_cond(txn_cond); list_destroy(format_list); return SLURM_ERROR; } if (!list_count(format_list)) { slurm_addto_char_list(format_list, "T,Action,Actor,Where,Info"); if (txn_cond->with_assoc_info) slurm_addto_char_list(format_list, "User,Account,Cluster"); } print_fields_list = sacctmgr_process_format_list(format_list); list_destroy(format_list); if (exit_code) { list_destroy(print_fields_list); return SLURM_ERROR; } txn_list = acct_storage_g_get_txn(db_conn, my_uid, txn_cond); slurmdb_destroy_txn_cond(txn_cond); if (!txn_list) { exit_code=1; fprintf(stderr, " Error with request: %s\n", slurm_strerror(errno)); list_destroy(print_fields_list); return SLURM_ERROR; } itr = list_iterator_create(txn_list); itr2 = list_iterator_create(print_fields_list); print_fields_header(print_fields_list); field_count = list_count(print_fields_list); while((txn = list_next(itr))) { int curr_inx = 1; while((field = list_next(itr2))) { switch(field->type) { case PRINT_ACCT: field->print_routine(field, txn->accts, (curr_inx == field_count)); break; case PRINT_ACTIONRAW: field->print_routine( field, txn->action, (curr_inx == field_count)); break; case PRINT_ACTION: field->print_routine( field, slurmdbd_msg_type_2_str(txn->action, 0), (curr_inx == field_count)); break; case PRINT_ACTOR: field->print_routine(field, txn->actor_name, (curr_inx == field_count)); break; case PRINT_CLUSTER: field->print_routine(field, txn->clusters, (curr_inx == field_count)); break; case PRINT_ID: field->print_routine(field, txn->id, (curr_inx == field_count)); break; case PRINT_INFO: field->print_routine(field, txn->set_info, (curr_inx == field_count)); break; case PRINT_TS: field->print_routine(field, txn->timestamp, (curr_inx == field_count)); break; case PRINT_USER: field->print_routine(field, txn->users, (curr_inx == field_count)); break; case PRINT_WHERE: field->print_routine(field, txn->where_query, (curr_inx == field_count)); break; default: field->print_routine(field, NULL, (curr_inx == field_count)); break; } curr_inx++; } list_iterator_reset(itr2); printf("\n"); } list_iterator_destroy(itr2); list_iterator_destroy(itr); list_destroy(txn_list); list_destroy(print_fields_list); return rc; }
/* when doing a select on this all the select should have a prefix of * t1. */ static int _setup_wckey_cond_limits(slurmdb_wckey_cond_t *wckey_cond, char **extra) { int set = 0; ListIterator itr = NULL; char *object = NULL; char *prefix = "t1"; if (!wckey_cond) return 0; if (wckey_cond->with_deleted) xstrfmtcat(*extra, " where (%s.deleted=0 || %s.deleted=1)", prefix, prefix); else xstrfmtcat(*extra, " where %s.deleted=0", prefix); if (wckey_cond->only_defs) { set = 1; xstrfmtcat(*extra, " && (%s.is_def=1)", prefix); } if (wckey_cond->name_list && list_count(wckey_cond->name_list)) { set = 0; xstrcat(*extra, " && ("); itr = list_iterator_create(wckey_cond->name_list); while ((object = list_next(itr))) { if (set) xstrcat(*extra, " || "); xstrfmtcat(*extra, "%s.wckey_name='%s'", prefix, object); set = 1; } list_iterator_destroy(itr); xstrcat(*extra, ")"); } if (wckey_cond->id_list && list_count(wckey_cond->id_list)) { set = 0; xstrcat(*extra, " && ("); itr = list_iterator_create(wckey_cond->id_list); while ((object = list_next(itr))) { if (set) xstrcat(*extra, " || "); xstrfmtcat(*extra, "%s.id_wckey=%s", prefix, object); set = 1; } list_iterator_destroy(itr); xstrcat(*extra, ")"); } if (wckey_cond->user_list && list_count(wckey_cond->user_list)) { set = 0; xstrcat(*extra, " && ("); itr = list_iterator_create(wckey_cond->user_list); while ((object = list_next(itr))) { if (set) xstrcat(*extra, " || "); xstrfmtcat(*extra, "%s.user='******'", prefix, object); set = 1; } list_iterator_destroy(itr); xstrcat(*extra, ")"); } return set; }
extern List as_mysql_modify_wckeys(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_wckey_cond_t *wckey_cond, slurmdb_wckey_rec_t *wckey) { List ret_list = NULL; int rc = SLURM_SUCCESS; char *extra = NULL, *object = NULL, *vals = NULL; char *user_name = NULL; List use_cluster_list = as_mysql_cluster_list; ListIterator itr; if (!wckey_cond || !wckey) { error("we need something to change"); return NULL; } if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) { if (wckey_cond->user_list && (list_count(wckey_cond->user_list) == 1)) { uid_t pw_uid; char *name; name = list_peek(wckey_cond->user_list); if ((uid_from_string (name, &pw_uid) >= 0) && (pw_uid == uid)) { /* Make sure they aren't trying to change something else and then set this association as a default. */ slurmdb_init_wckey_rec(wckey, 1); wckey->is_def = 1; goto is_same_user; } } error("Only admins can modify wckeys"); errno = ESLURM_ACCESS_DENIED; return NULL; } is_same_user: (void) _setup_wckey_cond_limits(wckey_cond, &extra); if (wckey->is_def == 1) xstrcat(vals, ", is_def=1"); if (!extra || !vals) { error("Nothing to modify '%s' '%s'", extra, vals); return NULL; } if (wckey_cond->cluster_list && list_count(wckey_cond->cluster_list)) use_cluster_list = wckey_cond->cluster_list; user_name = uid_to_string((uid_t) uid); if (use_cluster_list == as_mysql_cluster_list) slurm_mutex_lock(&as_mysql_cluster_list_lock); ret_list = list_create(slurm_destroy_char); itr = list_iterator_create(use_cluster_list); while ((object = list_next(itr))) { if ((rc = _cluster_modify_wckeys( mysql_conn, wckey, object, extra, vals, user_name, ret_list)) != SLURM_SUCCESS) break; } list_iterator_destroy(itr); xfree(extra); xfree(user_name); if (use_cluster_list == as_mysql_cluster_list) slurm_mutex_unlock(&as_mysql_cluster_list_lock); if (rc == SLURM_ERROR) { list_destroy(ret_list); ret_list = NULL; } return ret_list; }
static void _update_info_resv(List info_list, GtkTreeView *tree_view) { GtkTreeModel *model = gtk_tree_view_get_model(tree_view); static GtkTreeModel *last_model = NULL; reserve_info_t *resv_ptr = NULL; char *name = NULL; ListIterator itr = NULL; sview_resv_info_t *sview_resv_info = NULL; set_for_update(model, SORTID_UPDATED); itr = list_iterator_create(info_list); while ((sview_resv_info = (sview_resv_info_t*) list_next(itr))) { resv_ptr = sview_resv_info->resv_ptr; /* This means the tree_store changed (added new column or something). */ if (last_model != model) sview_resv_info->iter_set = false; if (sview_resv_info->iter_set) { gtk_tree_model_get(model, &sview_resv_info->iter_ptr, SORTID_NAME, &name, -1); if (strcmp(name, resv_ptr->name)) { /* Bad pointer */ sview_resv_info->iter_set = false; //g_print("bad resv iter pointer\n"); } g_free(name); } if (sview_resv_info->iter_set) { _update_resv_record(sview_resv_info, GTK_TREE_STORE(model)); } else { GtkTreePath *path = gtk_tree_path_new_first(); /* get the iter, or find out the list is empty * goto add */ if (gtk_tree_model_get_iter( model, &sview_resv_info->iter_ptr, path)) { do { /* search for the jobid and check to see if it is in the list */ gtk_tree_model_get( model, &sview_resv_info->iter_ptr, SORTID_NAME, &name, -1); if (!strcmp(name, resv_ptr->name)) { /* update with new info */ g_free(name); _update_resv_record( sview_resv_info, GTK_TREE_STORE(model)); sview_resv_info->iter_set = 1; break; } g_free(name); } while (gtk_tree_model_iter_next( model, &sview_resv_info->iter_ptr)); } if (!sview_resv_info->iter_set) { _append_resv_record(sview_resv_info, GTK_TREE_STORE(model)); sview_resv_info->iter_set = true; } gtk_tree_path_free(path); } } list_iterator_destroy(itr); /* remove all old reservations */ remove_old(model, SORTID_UPDATED); last_model = model; }
/* * We could load gres state or validate it using various mechanisms here. * This only validates that the configuration was specified in gres.conf. * In the general case, no code would need to be changed. */ extern int node_config_load(List gres_conf_list) { int i, rc = SLURM_SUCCESS; ListIterator iter; gres_slurmd_conf_t *gres_slurmd_conf; int nb_gpu = 0; /* Number of GPUs in the list */ int available_files_index = 0; xassert(gres_conf_list); iter = list_iterator_create(gres_conf_list); while ((gres_slurmd_conf = list_next(iter))) { if (strcmp(gres_slurmd_conf->name, gres_name)) continue; if (gres_slurmd_conf->file) nb_gpu++; } list_iterator_destroy(iter); gpu_devices = NULL; nb_available_files = -1; /* (Re-)Allocate memory if number of files changed */ if (nb_gpu > nb_available_files) { xfree(gpu_devices); /* No-op if NULL */ gpu_devices = (int *) xmalloc(sizeof(int) * nb_gpu); nb_available_files = nb_gpu; for (i = 0; i < nb_available_files; i++) gpu_devices[i] = -1; } iter = list_iterator_create(gres_conf_list); while ((gres_slurmd_conf = list_next(iter))) { if ((strcmp(gres_slurmd_conf->name, gres_name) == 0) && gres_slurmd_conf->file) { /* Populate gpu_devices array with number * at end of the file name */ char *bracket, *fname, *tmp_name; hostlist_t hl; bracket = strrchr(gres_slurmd_conf->file, '['); if (bracket) tmp_name = xstrdup(bracket); else tmp_name = xstrdup(gres_slurmd_conf->file); hl = hostlist_create(tmp_name); xfree(tmp_name); if (!hl) { rc = EINVAL; break; } while ((fname = hostlist_shift(hl))) { if (available_files_index == nb_available_files) { nb_available_files++; xrealloc(gpu_devices, sizeof(int) * nb_available_files); gpu_devices[available_files_index] = -1; } for (i = 0; fname[i]; i++) { if (!isdigit(fname[i])) continue; gpu_devices[available_files_index] = atoi(fname + i); break; } available_files_index++; free(fname); } hostlist_destroy(hl); } } list_iterator_destroy(iter); if (rc != SLURM_SUCCESS) fatal("%s failed to load configuration", plugin_name); for (i = 0; i < nb_available_files; i++) info("gpu %d is device number %d", i, gpu_devices[i]); return rc; }
/* * Synchronize BG block state to that of currently active jobs. * This can recover from slurmctld crashes when block usership * changes were queued */ extern int sync_jobs(List job_list) { ListIterator itr; struct job_record *job_ptr = NULL; List block_list = NULL; static bool run_already = false; bg_record_t *bg_record = NULL; /* Execute only on initial startup. We don't support bgblock * creation on demand today, so there is no need to re-sync data. */ if (run_already) return SLURM_SUCCESS; run_already = true; if (!job_list) { error("sync_jobs: no job_list"); return SLURM_ERROR; } slurm_mutex_lock(&block_state_mutex); /* Insure that all running jobs own the specified block */ itr = list_iterator_create(job_list); while ((job_ptr = list_next(itr))) { bg_action_t *bg_action_ptr = NULL; if (!IS_JOB_RUNNING(job_ptr) && !IS_JOB_COMPLETING(job_ptr)) continue; bg_action_ptr = xmalloc(sizeof(bg_action_t)); if (IS_JOB_COMPLETING(job_ptr)) bg_action_ptr->op = TERM_OP; else bg_action_ptr->op = START_OP; bg_action_ptr->job_ptr = job_ptr; get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_BLOCK_ID, &(bg_action_ptr->bg_block_id)); #ifdef HAVE_BG_L_P # ifdef HAVE_BGL get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_BLRTS_IMAGE, &(bg_action_ptr->blrtsimage)); # else get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_CONN_TYPE, &(bg_action_ptr->conn_type)); # endif get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_LINUX_IMAGE, &(bg_action_ptr->linuximage)); get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_RAMDISK_IMAGE, &(bg_action_ptr->ramdiskimage)); #endif get_select_jobinfo(job_ptr->select_jobinfo->data, SELECT_JOBDATA_MLOADER_IMAGE, &(bg_action_ptr->mloaderimage)); if (bg_action_ptr->bg_block_id == NULL) { error("Running job %u has bgblock==NULL", job_ptr->job_id); } else if (job_ptr->nodes == NULL) { error("Running job %u has nodes==NULL", job_ptr->job_id); } else if (!(bg_record = find_bg_record_in_list( bg_lists->main, bg_action_ptr->bg_block_id))) { error("Kill job %u belongs to defunct " "bgblock %s", job_ptr->job_id, bg_action_ptr->bg_block_id); } if (!bg_record) { /* Don't use slurm_fail_job, locks are already in place. */ job_fail(job_ptr->job_id); _destroy_bg_action(bg_action_ptr); continue; } /* _sync_agent will destroy the bg_action_ptr */ _sync_agent(bg_action_ptr, bg_record); } list_iterator_destroy(itr); block_list = list_create(destroy_bg_record); itr = list_iterator_create(bg_lists->main); while ((bg_record = list_next(itr))) { bg_record_t *rm_record; if (bg_record->job_ptr || (bg_record->job_list && list_count(bg_record->job_list))) continue; rm_record = xmalloc(sizeof(bg_record_t)); rm_record->magic = BLOCK_MAGIC; rm_record->bg_block_id = xstrdup(bg_record->bg_block_id); rm_record->mp_str = xstrdup(bg_record->mp_str); list_append(block_list, rm_record); } list_iterator_destroy(itr); slurm_mutex_unlock(&block_state_mutex); /* Insure that all other blocks are free of users */ if (block_list) { itr = list_iterator_create(block_list); while ((bg_record = list_next(itr))) { info("Queue clearing of users of BG block %s", bg_record->bg_block_id); term_jobs_on_block(bg_record->bg_block_id); } list_iterator_destroy(itr); list_destroy(block_list); } else { /* this should never happen, * vestigial logic */ error("sync_jobs: no block_list"); return SLURM_ERROR; } return SLURM_SUCCESS; }
extern void specific_info_resv(popup_info_t *popup_win) { int resv_error_code = SLURM_SUCCESS; static reserve_info_msg_t *resv_info_ptr = NULL; static reserve_info_t *resv_ptr = NULL; specific_info_t *spec_info = popup_win->spec_info; sview_search_info_t *search_info = spec_info->search_info; char error_char[100]; GtkWidget *label = NULL; GtkTreeView *tree_view = NULL; List resv_list = NULL; List send_resv_list = NULL; sview_resv_info_t *sview_resv_info_ptr = NULL; int j=0, i=-1; hostset_t hostset = NULL; ListIterator itr = NULL; if (!spec_info->display_widget) { setup_popup_info(popup_win, display_data_resv, SORTID_CNT); } if (spec_info->display_widget && popup_win->toggled) { gtk_widget_destroy(spec_info->display_widget); spec_info->display_widget = NULL; goto display_it; } if ((resv_error_code = get_new_info_resv(&resv_info_ptr, popup_win->force_refresh)) == SLURM_NO_CHANGE_IN_DATA) { if (!spec_info->display_widget || spec_info->view == ERROR_VIEW) goto display_it; } else if (resv_error_code != SLURM_SUCCESS) { if (spec_info->view == ERROR_VIEW) goto end_it; spec_info->view = ERROR_VIEW; if (spec_info->display_widget) gtk_widget_destroy(spec_info->display_widget); sprintf(error_char, "get_new_info_resv: %s", slurm_strerror(slurm_get_errno())); label = gtk_label_new(error_char); gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1); gtk_widget_show(label); spec_info->display_widget = gtk_widget_ref(label); goto end_it; } display_it: resv_list = _create_resv_info_list(resv_info_ptr); if (!resv_list) return; if (spec_info->view == ERROR_VIEW && spec_info->display_widget) { gtk_widget_destroy(spec_info->display_widget); spec_info->display_widget = NULL; } if (spec_info->type != INFO_PAGE && !spec_info->display_widget) { tree_view = create_treeview(local_display_data, &popup_win->grid_button_list); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(tree_view), GTK_SELECTION_MULTIPLE); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(popup_win->table, GTK_WIDGET(tree_view), 0, 1, 0, 1); /* since this function sets the model of the tree_view to the treestore we don't really care about the return value */ create_treestore(tree_view, popup_win->display_data, SORTID_CNT, SORTID_TIME_START, SORTID_COLOR); } setup_popup_grid_list(popup_win); spec_info->view = INFO_VIEW; if (spec_info->type == INFO_PAGE) { _display_info_resv(resv_list, popup_win); goto end_it; } /* just linking to another list, don't free the inside, just the list */ send_resv_list = list_create(NULL); itr = list_iterator_create(resv_list); i = -1; while ((sview_resv_info_ptr = list_next(itr))) { i++; resv_ptr = sview_resv_info_ptr->resv_ptr; switch(spec_info->type) { case PART_PAGE: case BLOCK_PAGE: case NODE_PAGE: if (!resv_ptr->node_list) continue; if (!(hostset = hostset_create( search_info->gchar_data))) continue; if (!hostset_intersects(hostset, resv_ptr->node_list)) { hostset_destroy(hostset); continue; } hostset_destroy(hostset); break; case JOB_PAGE: if (strcmp(resv_ptr->name, search_info->gchar_data)) continue; break; case RESV_PAGE: switch(search_info->search_type) { case SEARCH_RESERVATION_NAME: if (!search_info->gchar_data) continue; if (strcmp(resv_ptr->name, search_info->gchar_data)) continue; break; default: continue; } break; default: g_print("Unknown type %d\n", spec_info->type); continue; } list_push(send_resv_list, sview_resv_info_ptr); j=0; while (resv_ptr->node_inx[j] >= 0) { change_grid_color( popup_win->grid_button_list, resv_ptr->node_inx[j], resv_ptr->node_inx[j+1], sview_resv_info_ptr->color_inx, true, 0); j += 2; } } list_iterator_destroy(itr); post_setup_popup_grid_list(popup_win); _update_info_resv(send_resv_list, GTK_TREE_VIEW(spec_info->display_widget)); list_destroy(send_resv_list); end_it: popup_win->toggled = 0; popup_win->force_refresh = 0; return; }
static int args_parse_test(cmd_args_t *args, char *str) { ListIterator si, ti; subsystem_t *s; test_t *t; char *sub_str, *test_str; int sub_num, test_num; int sub_all = 0, test_all = 0; int rc, flag = 0; test_str = strchr(str, ':'); if (test_str == NULL) { fprintf(stderr, "Test must be of the " "form <subsystem:test>\n"); return -EINVAL; } sub_str = str; test_str[0] = '\0'; test_str = test_str + 1; sub_num = strtol(sub_str, NULL, 0); test_num = strtol(test_str, NULL, 0); if (!strncasecmp(sub_str, "all", strlen(sub_str)) || (sub_num == -1)) sub_all = 1; if (!strncasecmp(test_str,"all",strlen(test_str)) || (test_num == -1)) test_all = 1; si = list_iterator_create(subsystems); if (sub_all) { if (test_all) { /* Add all tests from all subsystems */ while ((s = list_next(si))) { ti = list_iterator_create(s->sub_tests); while ((t = list_next(ti))) { if ((rc = test_add(args, t))) { list_iterator_destroy(ti); goto error_run; } } list_iterator_destroy(ti); } } else { /* Add a specific test from all subsystems */ while ((s = list_next(si))) { if ((t=test_find(s->sub_desc.name,test_str))) { if ((rc = test_add(args, t))) goto error_run; flag = 1; } } if (!flag) fprintf(stderr, "No tests '%s:%s' could be " "found\n", sub_str, test_str); } } else { if (test_all) { /* Add all tests from a specific subsystem */ while ((s = list_next(si))) { if (strncasecmp(sub_str, s->sub_desc.name, strlen(sub_str))) continue; ti = list_iterator_create(s->sub_tests); while ((t = list_next(ti))) { if ((rc = test_add(args, t))) { list_iterator_destroy(ti); goto error_run; } } list_iterator_destroy(ti); } } else { /* Add a specific test from a specific subsystem */ if ((t = test_find(sub_str, test_str))) { if ((rc = test_add(args, t))) goto error_run; } else { fprintf(stderr, "Test '%s:%s' could not be " "found\n", sub_str, test_str); return -EINVAL; } } } list_iterator_destroy(si); return 0; error_run: list_iterator_destroy(si); fprintf(stderr, "Test '%s:%s' not added to run list: %d\n", sub_str, test_str, rc); return rc; }
static int dev_init(void) { ListIterator i; subsystem_t *sub; int rc; splatctl_fd = open(SPLAT_DEV, O_RDONLY); if (splatctl_fd == -1) { fprintf(stderr, "Unable to open %s: %d\n" "Is the splat module loaded?\n", SPLAT_DEV, errno); rc = errno; goto error; } /* Determine kernel module version string */ memset(splat_version, 0, VERSION_SIZE); if ((rc = read(splatctl_fd, splat_version, VERSION_SIZE - 1)) == -1) goto error; if ((rc = dev_clear())) goto error; if ((rc = dev_size(0)) < 0) goto error; splat_buffer_size = rc; splat_buffer = (char *)malloc(splat_buffer_size); if (splat_buffer == NULL) { rc = -ENOMEM; goto error; } memset(splat_buffer, 0, splat_buffer_size); /* Determine available subsystems */ if ((rc = subsystem_setup()) != 0) goto error; /* Determine available tests for all subsystems */ i = list_iterator_create(subsystems); while ((sub = list_next(i))) { if ((rc = test_setup(sub)) != 0) { list_iterator_destroy(i); goto error; } } list_iterator_destroy(i); return 0; error: if (splatctl_fd != -1) { if (close(splatctl_fd) == -1) { fprintf(stderr, "Unable to close %s: %d\n", SPLAT_DEV, errno); } } return rc; }
/* FIXME: This only works for CPUS now */ static List _process_grouped_report( void *db_conn, slurmdb_job_cond_t *job_cond, List grouping_list, bool flat_view, bool wckey_type, bool both) { int exit_code = 0; void *object = NULL, *object2 = NULL; ListIterator itr = NULL, itr2 = NULL; ListIterator cluster_itr = NULL; ListIterator local_itr = NULL; ListIterator acct_itr = NULL; ListIterator group_itr = NULL; slurmdb_job_rec_t *job = NULL; slurmdb_report_cluster_grouping_t *cluster_group = NULL; slurmdb_report_acct_grouping_t *acct_group = NULL; slurmdb_report_job_grouping_t *job_group = NULL; List job_list = NULL; List cluster_list = NULL; List object_list = NULL, object2_list = NULL; List tmp_acct_list = NULL; bool destroy_job_cond = 0; bool destroy_grouping_list = 0; bool individual = 0; uint32_t tres_id = TRES_CPU; uid_t my_uid = getuid(); /* we don't want to actually query by accounts in the jobs here since we may be looking for sub accounts of a specific account. */ if (!job_cond) { destroy_job_cond = 1; job_cond = xmalloc(sizeof(slurmdb_job_cond_t)); } if (!grouping_list) { destroy_grouping_list = 1; grouping_list = list_create(slurm_destroy_char); slurm_addto_char_list(grouping_list, "50,250,500,1000"); } tmp_acct_list = job_cond->acct_list; job_cond->acct_list = NULL; job_list = jobacct_storage_g_get_jobs_cond(db_conn, my_uid, job_cond); job_cond->acct_list = tmp_acct_list; tmp_acct_list = NULL; if (!job_list) { exit_code=1; fprintf(stderr, " Problem with job query.\n"); goto end_it; } group_itr = list_iterator_create(grouping_list); /* make a group for each job size we find. */ if (!list_count(grouping_list)) { char *group = NULL; individual = 1; itr = list_iterator_create(job_list); while ((job = list_next(itr))) { char *tmp = NULL; uint64_t count; if (!job->elapsed) continue; if ((count = slurmdb_find_tres_count_in_string( job->tres_alloc_str, tres_id)) == INFINITE64) continue; tmp = xstrdup_printf("%"PRIu64, count); while ((group = list_next(group_itr))) { if (!strcmp(group, tmp)) { break; } } if (!group) list_append(grouping_list, tmp); else xfree(tmp); list_iterator_reset(group_itr); } list_iterator_destroy(itr); list_sort(grouping_list, (ListCmpF)_sort_group_asc); } cluster_list = list_create(slurmdb_destroy_report_cluster_grouping); cluster_itr = list_iterator_create(cluster_list); if (flat_view) goto no_objects; if (!wckey_type || both) { slurmdb_assoc_cond_t assoc_cond; memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t)); assoc_cond.id_list = job_cond->associd_list; assoc_cond.cluster_list = job_cond->cluster_list; /* don't limit associations to having the partition_list */ //assoc_cond.partition_list = job_cond->partition_list; if (!job_cond->acct_list || !list_count(job_cond->acct_list)) { FREE_NULL_LIST(job_cond->acct_list); job_cond->acct_list = list_create(NULL); list_append(job_cond->acct_list, "root"); } assoc_cond.parent_acct_list = job_cond->acct_list; object_list = acct_storage_g_get_assocs(db_conn, my_uid, &assoc_cond); } if (wckey_type || both) { slurmdb_wckey_cond_t wckey_cond; memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t)); wckey_cond.name_list = job_cond->wckey_list; wckey_cond.cluster_list = job_cond->cluster_list; object2_list = acct_storage_g_get_wckeys(db_conn, my_uid, &wckey_cond); if (!object_list) { object_list = object2_list; object2_list = NULL; } } if (!object_list) { debug2(" No join list given.\n"); goto no_objects; } itr = list_iterator_create(object_list); if (object2_list) itr2 = list_iterator_create(object2_list); while ((object = list_next(itr))) { char *cluster = NULL; slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object; slurmdb_assoc_rec_t *assoc = (slurmdb_assoc_rec_t *)object; if (!itr2) { char *name = NULL; if (wckey_type) { cluster = wckey->cluster; name = wckey->name; } else { cluster = assoc->cluster; name = assoc->acct; } _check_create_grouping(cluster_list, group_itr, cluster, name, object, individual, wckey_type); continue; } while ((object2 = list_next(itr2))) { slurmdb_wckey_rec_t *wckey2 = (slurmdb_wckey_rec_t *)object2; slurmdb_assoc_rec_t *assoc2 = (slurmdb_assoc_rec_t *)object2; char name[200]; if (!wckey_type) { if (strcmp(assoc->cluster, wckey2->cluster)) continue; cluster = assoc->cluster; snprintf(name, sizeof(name), "%s:%s", assoc->acct, wckey2->name); } else { if (strcmp(wckey->cluster, assoc2->cluster)) continue; cluster = wckey->cluster; snprintf(name, sizeof(name), "%s:%s", wckey2->name, assoc->acct); } _check_create_grouping(cluster_list, group_itr, cluster, name, object, individual, wckey_type); } list_iterator_reset(itr2); } list_iterator_destroy(itr); if (itr2) list_iterator_destroy(itr2); no_objects: itr = list_iterator_create(job_list); while((job = list_next(itr))) { char *local_cluster = "UNKNOWN"; char tmp_acct[200]; if (!job->elapsed) { /* here we don't care about jobs that didn't * really run here */ continue; } if (job->cluster) local_cluster = job->cluster; if (!wckey_type) { if (both && job->wckey) { snprintf(tmp_acct, sizeof(tmp_acct), "%s:%s", job->account, job->wckey); } else { snprintf(tmp_acct, sizeof(tmp_acct), "%s", job->account); } } else { if (both && job->account) { snprintf(tmp_acct, sizeof(tmp_acct), "%s:%s", job->wckey, job->account); } else { snprintf(tmp_acct, sizeof(tmp_acct), "%s", job->wckey); } } list_iterator_reset(cluster_itr); while((cluster_group = list_next(cluster_itr))) { if (!strcmp(local_cluster, cluster_group->cluster)) break; } if (!cluster_group) { /* here we are only looking for groups that * were added with the associations above */ if (!flat_view) continue; cluster_group = xmalloc( sizeof(slurmdb_report_cluster_grouping_t)); cluster_group->cluster = xstrdup(local_cluster); cluster_group->acct_list = list_create( slurmdb_destroy_report_acct_grouping); list_append(cluster_list, cluster_group); } acct_itr = list_iterator_create(cluster_group->acct_list); while((acct_group = list_next(acct_itr))) { if (wckey_type) { if (!strcmp(tmp_acct, acct_group->acct)) break; continue; } if (!flat_view && (acct_group->lft != (uint32_t)NO_VAL) && (job->lft != (uint32_t)NO_VAL)) { /* keep separate since we don't want * to so a strcmp if we don't have to */ if (job->lft > acct_group->lft && job->lft < acct_group->rgt) { char *mywckey; if (!both) break; mywckey = strstr(acct_group->acct, ":"); mywckey++; if (!job->wckey && !mywckey) break; else if (!mywckey || !job->wckey) continue; else if (!strcmp(mywckey, job->wckey)) break; } } else if (!strcmp(acct_group->acct, tmp_acct)) break; } list_iterator_destroy(acct_itr); if (!acct_group) { char *group = NULL; uint32_t last_size = 0; /* here we are only looking for groups that * were added with the associations above */ if (!flat_view) continue; acct_group = xmalloc( sizeof(slurmdb_report_acct_grouping_t)); acct_group->acct = xstrdup(tmp_acct); acct_group->groups = list_create( slurmdb_destroy_report_job_grouping); list_append(cluster_group->acct_list, acct_group); while((group = list_next(group_itr))) { job_group = xmalloc( sizeof(slurmdb_report_job_grouping_t)); job_group->jobs = list_create(NULL); if (!individual) job_group->min_size = last_size; last_size = atoi(group); if (!individual) job_group->max_size = last_size-1; else job_group->min_size = job_group->max_size = last_size; list_append(acct_group->groups, job_group); } if (last_size && !individual) { job_group = xmalloc( sizeof(slurmdb_report_job_grouping_t)); job_group->jobs = list_create(NULL); job_group->min_size = last_size; if (individual) job_group->max_size = job_group->min_size; else job_group->max_size = INFINITE; list_append(acct_group->groups, job_group); } list_iterator_reset(group_itr); } local_itr = list_iterator_create(acct_group->groups); while ((job_group = list_next(local_itr))) { uint64_t count; if (((count = slurmdb_find_tres_count_in_string( job->tres_alloc_str, tres_id)) == INFINITE64) || (count < job_group->min_size) || (count > job_group->max_size)) continue; list_append(job_group->jobs, job); job_group->count++; acct_group->count++; cluster_group->count++; slurmdb_transfer_tres_time( &job_group->tres_list, job->tres_alloc_str, job->elapsed); slurmdb_transfer_tres_time( &acct_group->tres_list, job->tres_alloc_str, job->elapsed); slurmdb_transfer_tres_time( &cluster_group->tres_list, job->tres_alloc_str, job->elapsed); } list_iterator_destroy(local_itr); } list_iterator_destroy(itr); list_iterator_destroy(group_itr); list_iterator_reset(cluster_itr); while ((cluster_group = list_next(cluster_itr))) { ListIterator acct_itr; if (!cluster_group->count) { list_delete_item(cluster_itr); continue; } acct_itr = list_iterator_create(cluster_group->acct_list); while ((acct_group = list_next(acct_itr))) { if (!acct_group->count) { list_delete_item(acct_itr); continue; } } list_iterator_destroy(acct_itr); } list_iterator_destroy(cluster_itr); end_it: FREE_NULL_LIST(object_list); FREE_NULL_LIST(object2_list); if (destroy_job_cond) slurmdb_destroy_job_cond(job_cond); if (destroy_grouping_list) FREE_NULL_LIST(grouping_list); if (exit_code) { FREE_NULL_LIST(cluster_list); } return cluster_list; }
static void _check_create_grouping( List cluster_list, ListIterator group_itr, char *cluster, char *name, void *object, bool individual, bool wckey_type) { ListIterator itr; slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object; slurmdb_assoc_rec_t *assoc = (slurmdb_assoc_rec_t *)object; slurmdb_report_cluster_grouping_t *cluster_group = NULL; slurmdb_report_acct_grouping_t *acct_group = NULL; slurmdb_report_job_grouping_t *job_group = NULL; itr = list_iterator_create(cluster_list); while((cluster_group = list_next(itr))) { if (!strcmp(cluster, cluster_group->cluster)) break; } list_iterator_destroy(itr); if (!cluster_group) { cluster_group = xmalloc( sizeof(slurmdb_report_cluster_grouping_t)); cluster_group->cluster = xstrdup(cluster); cluster_group->acct_list = list_create( slurmdb_destroy_report_acct_grouping); list_append(cluster_list, cluster_group); } itr = list_iterator_create(cluster_group->acct_list); while ((acct_group = list_next(itr))) { if (!strcmp(name, acct_group->acct)) break; } list_iterator_destroy(itr); if (!acct_group) { uint32_t last_size = 0; char *group = NULL; acct_group = xmalloc(sizeof(slurmdb_report_acct_grouping_t)); acct_group->acct = xstrdup(name); if (wckey_type) acct_group->lft = wckey->id; else { acct_group->lft = assoc->lft; acct_group->rgt = assoc->rgt; } acct_group->groups = list_create( slurmdb_destroy_report_job_grouping); list_append(cluster_group->acct_list, acct_group); while ((group = list_next(group_itr))) { job_group = xmalloc( sizeof(slurmdb_report_job_grouping_t)); job_group->jobs = list_create(NULL); if (!individual) job_group->min_size = last_size; last_size = atoi(group); if (!individual) job_group->max_size = last_size-1; else job_group->min_size = job_group->max_size = last_size; list_append(acct_group->groups, job_group); } if (last_size && !individual) { job_group = xmalloc( sizeof(slurmdb_report_job_grouping_t)); job_group->jobs = list_create(NULL); job_group->min_size = last_size; if (individual) job_group->max_size = job_group->min_size; else job_group->max_size = INFINITE; list_append(acct_group->groups, job_group); } list_iterator_reset(group_itr); } }
static int _breakup_blocks(List block_list, List new_blocks, select_ba_request_t *request, List my_block_list, int cnodes, bool only_free, bool only_small) { int rc = SLURM_ERROR; bg_record_t *bg_record = NULL; ListIterator itr = NULL, bit_itr = NULL; int total_cnode_cnt=0; char start_char[SYSTEM_DIMENSIONS+1]; bitstr_t *ionodes = bit_alloc(bg_conf->ionodes_per_mp); int curr_mp_bit = -1; int dim; if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("cpu_count=%d cnodes=%d o_free=%d o_small=%d", request->procs, cnodes, only_free, only_small); switch(cnodes) { case 16: /* a 16 can go anywhere */ break; case 32: bit_itr = list_iterator_create(bg_lists->valid_small32); break; case 64: bit_itr = list_iterator_create(bg_lists->valid_small64); break; case 128: bit_itr = list_iterator_create(bg_lists->valid_small128); break; case 256: bit_itr = list_iterator_create(bg_lists->valid_small256); break; default: error("We shouldn't be here with this size %d", cnodes); goto finished; break; } /* First try with free blocks a midplane or less. Then try with the * smallest blocks. */ itr = list_iterator_create(block_list); while ((bg_record = list_next(itr))) { /* If the free_cnt is -1 that just means we just didn't add it to the system, in this case it is probably a small block that we really should be looking at. */ if (bg_record->free_cnt > 0) { if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("%s being freed by other job(s), skipping", bg_record->bg_block_id); continue; } /* never look at a block if a job is running */ if ((bg_record->job_running != NO_JOB_RUNNING) || (bg_record->job_list && list_count(bg_record->job_list))) continue; /* on the third time through look for just a block * that isn't used */ /* check for free blocks on the first and second time */ if (only_free && (bg_record->state != BG_BLOCK_FREE)) continue; /* check small blocks first */ if (only_small && (bg_record->cnode_cnt >= bg_conf->mp_cnode_cnt)) continue; if (request->avail_mp_bitmap && !bit_super_set(bg_record->mp_bitmap, request->avail_mp_bitmap)) { if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("bg block %s has nodes not usable " "by this job", bg_record->bg_block_id); continue; } if (bg_record->cnode_cnt == cnodes) { ba_mp_t *ba_mp = NULL; if (bg_record->ba_mp_list) ba_mp = list_peek(bg_record->ba_mp_list); if (!ba_mp) { for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) start_char[dim] = alpha_num[ bg_record->start[dim]]; start_char[dim] = '\0'; request->save_name = xstrdup(start_char); } else request->save_name = xstrdup(ba_mp->coord_str); rc = SLURM_SUCCESS; goto finished; } /* lets see if we can combine some small ones */ if (bg_record->cnode_cnt < cnodes) { char bitstring[BITSIZE]; bitstr_t *bitstr = NULL; int num_over = 0; int num_cnodes = bg_record->cnode_cnt; int rec_mp_bit = bit_ffs(bg_record->mp_bitmap); if (curr_mp_bit != rec_mp_bit) { /* Got a different node than * previously, since the list should * be in order of nodes for small blocks * just clear here since the last node * doesn't have any more. */ curr_mp_bit = rec_mp_bit; bit_nclear(ionodes, 0, (bg_conf->ionodes_per_mp-1)); total_cnode_cnt = 0; } /* On really busy systems we can get overlapping blocks here. If that is the case only add that which doesn't overlap. */ if ((num_over = bit_overlap( ionodes, bg_record->ionode_bitmap))) { /* Since the smallest block size is the number of cnodes in an io node, just multiply the num_over by that to get the number of cnodes to remove. */ if ((num_cnodes -= num_over * bg_conf->smallest_block) <= 0) continue; } bit_or(ionodes, bg_record->ionode_bitmap); /* check and see if the bits set are a valid combo */ if (bit_itr) { while ((bitstr = list_next(bit_itr))) { if (bit_super_set(ionodes, bitstr)) break; } list_iterator_reset(bit_itr); } if (!bitstr) { bit_nclear(ionodes, 0, (bg_conf->ionodes_per_mp-1)); bit_or(ionodes, bg_record->ionode_bitmap); total_cnode_cnt = num_cnodes = bg_record->cnode_cnt; } else total_cnode_cnt += num_cnodes; bit_fmt(bitstring, BITSIZE, ionodes); if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("combine adding %s %s %d got %d set " "ionodes %s total is %s", bg_record->bg_block_id, bg_record->mp_str, num_cnodes, total_cnode_cnt, bg_record->ionode_str, bitstring); if (total_cnode_cnt == cnodes) { ba_mp_t *ba_mp = NULL; if (bg_record->ba_mp_list) ba_mp = list_peek( bg_record->ba_mp_list); if (!ba_mp) { for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) start_char[dim] = alpha_num[ bg_record->start[dim]]; start_char[dim] = '\0'; request->save_name = xstrdup(start_char); } else request->save_name = xstrdup(ba_mp->coord_str); if (!my_block_list) { rc = SLURM_SUCCESS; goto finished; } bg_record = create_small_record(bg_record, ionodes, cnodes); list_append(new_blocks, bg_record); rc = SLURM_SUCCESS; goto finished; } continue; } /* we found a block that is bigger than requested */ break; } if (bg_record) { ba_mp_t *ba_mp = NULL; if (bg_record->ba_mp_list) ba_mp = list_peek(bg_record->ba_mp_list); if (!ba_mp) { for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) start_char[dim] = alpha_num[ bg_record->start[dim]]; start_char[dim] = '\0'; request->save_name = xstrdup(start_char); } else request->save_name = xstrdup(ba_mp->coord_str); /* It appears we don't need this original record * anymore, just work off the copy if indeed it is a copy. */ /* bg_record_t *found_record = NULL; */ /* if (bg_record->original) { */ /* if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) */ /* info("1 This was a copy %s", */ /* bg_record->bg_block_id); */ /* found_record = bg_record->original; */ /* } else { */ /* if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) */ /* info("looking for original"); */ /* found_record = find_org_in_bg_list( */ /* bg_lists->main, bg_record); */ /* } */ if ((bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) && bg_record->original && (bg_record->original->magic != BLOCK_MAGIC)) { info("This record %s has bad magic, it must be " "getting freed. No worries it will all be " "figured out later.", bg_record->bg_block_id); } /* if (!found_record || found_record->magic != BLOCK_MAGIC) { */ /* error("this record wasn't found in the list!"); */ /* rc = SLURM_ERROR; */ /* goto finished; */ /* } */ if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) { char tmp_char[256]; format_node_name(bg_record, tmp_char, sizeof(tmp_char)); info("going to split %s, %s", bg_record->bg_block_id, tmp_char); } if (!my_block_list) { rc = SLURM_SUCCESS; goto finished; } _split_block(block_list, new_blocks, bg_record, cnodes); rc = SLURM_SUCCESS; goto finished; } finished: if (bit_itr) list_iterator_destroy(bit_itr); FREE_NULL_BITMAP(ionodes); if (itr) list_iterator_destroy(itr); return rc; }
/* * create_dynamic_block - create new block(s) to be used for a new * job allocation. * RET - a list of created block(s) or NULL on failure errno is set. */ extern List create_dynamic_block(List block_list, select_ba_request_t *request, List my_block_list, bool track_down_nodes) { int rc = SLURM_SUCCESS; ListIterator itr, itr2; bg_record_t *bg_record = NULL, *found_record = NULL; List results = NULL; List new_blocks = NULL; bitstr_t *my_bitmap = NULL; select_ba_request_t blockreq; int cnodes = request->procs / bg_conf->cpu_ratio; int orig_cnodes; uint16_t start_geo[SYSTEM_DIMENSIONS]; if (cnodes < bg_conf->smallest_block) cnodes = bg_conf->smallest_block; orig_cnodes = cnodes; if (bg_conf->sub_blocks && (cnodes < bg_conf->mp_cnode_cnt)) { cnodes = bg_conf->mp_cnode_cnt; request->conn_type[0] = SELECT_TORUS; } else if (cnodes < bg_conf->smallest_block) { error("Can't create this size %d " "on this system the smallest block is %u", cnodes, bg_conf->smallest_block); goto finished; } memset(&blockreq, 0, sizeof(select_ba_request_t)); memcpy(start_geo, request->geometry, sizeof(start_geo)); /* We need to lock this just incase a blocks_overlap is called which will in turn reset and set the system as it sees fit. */ slurm_mutex_lock(&block_state_mutex); if (my_block_list) { reset_ba_system(track_down_nodes); itr = list_iterator_create(my_block_list); while ((bg_record = list_next(itr))) { if (bg_record->magic != BLOCK_MAGIC) { /* This should never happen since we only call this on copies of blocks and we check on this during the copy. */ error("create_dynamic_block: " "got a block with bad magic?"); continue; } if (bg_record->free_cnt) { if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) { int dim; char start_geo[SYSTEM_DIMENSIONS+1]; char geo[SYSTEM_DIMENSIONS+1]; for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) { start_geo[dim] = alpha_num[ bg_record->start[dim]]; geo[dim] = alpha_num[ bg_record->geo[dim]]; } start_geo[dim] = '\0'; geo[dim] = '\0'; info("not adding %s(%s) %s %s %s %u " "(free_cnt)", bg_record->bg_block_id, bg_record->mp_str, bg_block_state_string( bg_record->state), start_geo, geo, bg_record->cnode_cnt); } continue; } if (!my_bitmap) my_bitmap = bit_alloc( bit_size(bg_record->mp_bitmap)); if (!bit_super_set(bg_record->mp_bitmap, my_bitmap)) { bit_or(my_bitmap, bg_record->mp_bitmap); if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) { int dim; char start_geo[SYSTEM_DIMENSIONS+1]; char geo[SYSTEM_DIMENSIONS+1]; for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) { start_geo[dim] = alpha_num[ bg_record->start[dim]]; geo[dim] = alpha_num[ bg_record->geo[dim]]; } start_geo[dim] = '\0'; geo[dim] = '\0'; info("adding %s(%s) %s %s %s %u", bg_record->bg_block_id, bg_record->mp_str, bg_block_state_string( bg_record->state), start_geo, geo, bg_record->cnode_cnt); } if (check_and_set_mp_list( bg_record->ba_mp_list) == SLURM_ERROR) { if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("something happened in " "the load of %s", bg_record->bg_block_id); list_iterator_destroy(itr); FREE_NULL_BITMAP(my_bitmap); rc = SLURM_ERROR; goto finished; } } else { if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) { int dim; char start_geo[SYSTEM_DIMENSIONS+1]; char geo[SYSTEM_DIMENSIONS+1]; for (dim=0; dim<SYSTEM_DIMENSIONS; dim++) { start_geo[dim] = alpha_num[ bg_record->start[dim]]; geo[dim] = alpha_num[ bg_record->geo[dim]]; } start_geo[dim] = '\0'; geo[dim] = '\0'; info("not adding %s(%s) %s %s %s %u ", bg_record->bg_block_id, bg_record->mp_str, bg_block_state_string( bg_record->state), start_geo, geo, bg_record->cnode_cnt); } /* just so we don't look at it later */ bg_record->free_cnt = -1; } } list_iterator_destroy(itr); FREE_NULL_BITMAP(my_bitmap); } else { reset_ba_system(false); if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("No list was given"); } if (request->avail_mp_bitmap) ba_set_removable_mps(request->avail_mp_bitmap, 1); try_small_again: if (request->size==1 && cnodes < bg_conf->mp_cnode_cnt) { switch(cnodes) { #ifdef HAVE_BGL case 32: blockreq.small32 = 4; blockreq.small128 = 3; break; case 128: blockreq.small128 = 4; break; #else case 16: blockreq.small16 = 2; blockreq.small32 = 1; blockreq.small64 = 1; blockreq.small128 = 1; blockreq.small256 = 1; break; case 32: blockreq.small32 = 2; blockreq.small64 = 1; blockreq.small128 = 1; blockreq.small256 = 1; break; case 64: blockreq.small64 = 2; blockreq.small128 = 1; blockreq.small256 = 1; break; case 128: blockreq.small128 = 2; blockreq.small256 = 1; break; case 256: blockreq.small256 = 2; break; #endif default: error("This size %d is unknown on this system", cnodes); goto finished; break; } /* Sort the list so the small blocks are in the order * of ionodes. */ list_sort(block_list, (ListCmpF)bg_record_cmpf_inc); request->conn_type[0] = SELECT_SMALL; new_blocks = list_create(destroy_bg_record); /* check only blocks that are free and small */ if (_breakup_blocks(block_list, new_blocks, request, my_block_list, cnodes, true, true) == SLURM_SUCCESS) goto finished; /* check only blocks that are free and any size */ if (_breakup_blocks(block_list, new_blocks, request, my_block_list, cnodes, true, false) == SLURM_SUCCESS) goto finished; /* check usable blocks that are small with any state */ if (_breakup_blocks(block_list, new_blocks, request, my_block_list, cnodes, false, true) == SLURM_SUCCESS) goto finished; /* check all usable blocks */ /* This check will result in unused, booted blocks to be freed before looking at free space, so we will just skip it. If you want this kind of behavior enable it. */ /* if (_breakup_blocks(block_list, new_blocks, */ /* request, my_block_list, */ /* cnodes, false, false) */ /* == SLURM_SUCCESS) */ /* goto finished; */ /* Re-sort the list back to the original order. */ list_sort(block_list, (ListCmpF)bg_record_sort_aval_inc); list_destroy(new_blocks); new_blocks = NULL; if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("small block not able to be placed inside others"); } //debug("going to create %d", request->size); if (!new_ba_request(request)) { if (request->geometry[0] != (uint16_t)NO_VAL) { char *geo = give_geo(request->geometry, SYSTEM_DIMENSIONS, 1); error("Problems with request for size %d geo %s", request->size, geo); xfree(geo); } else { error("Problems with request for size %d. " "No geo given.", request->size); } rc = ESLURM_INTERCONNECT_FAILURE; goto finished; } /* try on free midplanes */ rc = SLURM_SUCCESS; if (results) list_flush(results); else { #ifdef HAVE_BGQ results = list_create(destroy_ba_mp); #else results = list_create(NULL); #endif } rc = allocate_block(request, results); /* This could be changed in allocate_block so set it back up */ memcpy(request->geometry, start_geo, sizeof(start_geo)); if (rc) { rc = SLURM_SUCCESS; goto setup_records; } if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("allocate failure for %d midplanes with free midplanes", request->size); rc = SLURM_ERROR; if (!list_count(my_block_list) || !my_block_list) goto finished; /*Try to put block starting in the smallest of the exisiting blocks*/ itr = list_iterator_create(my_block_list); itr2 = list_iterator_create(my_block_list); while ((bg_record = (bg_record_t *) list_next(itr)) != NULL) { bool is_small = 0; /* never check a block with a job running */ if (bg_record->free_cnt || ((bg_record->job_running != NO_JOB_RUNNING) || (bg_record->job_list && list_count(bg_record->job_list)))) continue; /* Here we are only looking for the first block on the midplane. So either the count is greater or equal than bg_conf->mp_cnode_cnt or the first bit is set in the ionode_bitmap. */ if (bg_record->cnode_cnt < bg_conf->mp_cnode_cnt) { bool found = 0; if (bit_ffs(bg_record->ionode_bitmap) != 0) continue; /* Check to see if we have other blocks in this midplane that have jobs running. */ while ((found_record = list_next(itr2))) { /* Don't check free_cnt here since if this block shares the same midplane it will automatically be -1. So just look for running jobs. */ if (((found_record->job_running != NO_JOB_RUNNING) || (found_record->job_list && list_count(found_record->job_list))) && bit_overlap(bg_record->mp_bitmap, found_record->mp_bitmap)) { found = 1; break; } } list_iterator_reset(itr2); if (found) continue; is_small = 1; } if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("removing %s(%s) for request %d", bg_record->bg_block_id, bg_record->mp_str, request->size); remove_block(bg_record->ba_mp_list, is_small); rc = SLURM_SUCCESS; if (results) list_flush(results); else { #ifdef HAVE_BGQ results = list_create(destroy_ba_mp); #else results = list_create(NULL); #endif } rc = allocate_block(request, results); /* This could be changed in allocate_block so set it back up */ memcpy(request->geometry, start_geo, sizeof(start_geo)); if (rc) { rc = SLURM_SUCCESS; break; } if (bg_conf->slurm_debug_flags & DEBUG_FLAG_BG_PICK) info("allocate failure for size %d base partitions", request->size); rc = SLURM_ERROR; } list_iterator_destroy(itr); list_iterator_destroy(itr2); setup_records: if (rc == SLURM_SUCCESS) { /*set up bg_record(s) here */ new_blocks = list_create(destroy_bg_record); blockreq.save_name = request->save_name; #ifdef HAVE_BGL blockreq.blrtsimage = request->blrtsimage; #endif blockreq.linuximage = request->linuximage; blockreq.mloaderimage = request->mloaderimage; blockreq.ramdiskimage = request->ramdiskimage; memcpy(blockreq.start, request->start, sizeof(blockreq.start)); memcpy(blockreq.conn_type, request->conn_type, sizeof(blockreq.conn_type)); add_bg_record(new_blocks, &results, &blockreq, 0, 0); } finished: if (!new_blocks && orig_cnodes != cnodes) { cnodes = orig_cnodes; goto try_small_again; } if (request->avail_mp_bitmap && (bit_ffc(request->avail_mp_bitmap) == -1)) ba_reset_all_removed_mps(); slurm_mutex_unlock(&block_state_mutex); /* reset the ones we mucked with */ itr = list_iterator_create(my_block_list); while ((bg_record = (bg_record_t *) list_next(itr))) { if (bg_record->free_cnt == -1) bg_record->free_cnt = 0; } list_iterator_destroy(itr); xfree(request->save_name); if (results) { list_destroy(results); results = NULL; } errno = rc; return new_blocks; }
static int _set_cond(int *start, int argc, char *argv[], slurmdb_txn_cond_t *txn_cond, List format_list) { int i, end = 0; int set = 0; int command_len = 0; for (i=(*start); i<argc; i++) { end = parse_option_end(argv[i]); if (!end) command_len=strlen(argv[i]); else { command_len=end-1; if (argv[i][end] == '=') { end++; } } if (!end && !strncasecmp(argv[i], "where", MAX(command_len, 5))) { continue; } else if (!end && !strncasecmp(argv[i], "withassocinfo", MAX(command_len, 5))) { txn_cond->with_assoc_info = 1; set = 1; } else if (!end || (!strncasecmp (argv[i], "Ids", MAX(command_len, 1))) || (!strncasecmp (argv[i], "Txn", MAX(command_len, 1)))) { ListIterator itr = NULL; char *temp = NULL; uint32_t id = 0; if (!txn_cond->id_list) txn_cond->id_list = list_create(slurm_destroy_char); if (slurm_addto_char_list(txn_cond->id_list, argv[i]+end)) set = 1; /* check to make sure user gave ints here */ itr = list_iterator_create(txn_cond->id_list); while ((temp = list_next(itr))) { if (get_uint(temp, &id, "Transaction ID") != SLURM_SUCCESS) { exit_code = 1; list_delete_item(itr); } } list_iterator_destroy(itr); } else if (!strncasecmp (argv[i], "Accounts", MAX(command_len, 3))) { if (!txn_cond->acct_list) txn_cond->acct_list = list_create(slurm_destroy_char); if (slurm_addto_char_list(txn_cond->acct_list, argv[i]+end)) set = 1; } else if (!strncasecmp (argv[i], "Action", MAX(command_len, 4))) { if (!txn_cond->action_list) txn_cond->action_list = list_create(slurm_destroy_char); if (addto_action_char_list(txn_cond->action_list, argv[i]+end)) set = 1; else exit_code=1; } else if (!strncasecmp (argv[i], "Actors", MAX(command_len, 4))) { if (!txn_cond->actor_list) txn_cond->actor_list = list_create(slurm_destroy_char); if (slurm_addto_char_list(txn_cond->actor_list, argv[i]+end)) set = 1; } else if (!strncasecmp (argv[i], "Clusters", MAX(command_len, 3))) { if (!txn_cond->cluster_list) txn_cond->cluster_list = list_create(slurm_destroy_char); if (slurm_addto_char_list(txn_cond->cluster_list, argv[i]+end)) set = 1; } else if (!strncasecmp (argv[i], "End", MAX(command_len, 1))) { txn_cond->time_end = parse_time(argv[i]+end, 1); set = 1; } else if (!strncasecmp (argv[i], "Format", MAX(command_len, 1))) { if (format_list) slurm_addto_char_list(format_list, argv[i]+end); } else if (!strncasecmp (argv[i], "Start", MAX(command_len, 1))) { txn_cond->time_start = parse_time(argv[i]+end, 1); set = 1; } else if (!strncasecmp (argv[i], "Users", MAX(command_len, 1))) { if (!txn_cond->user_list) txn_cond->user_list = list_create(slurm_destroy_char); if (slurm_addto_char_list(txn_cond->user_list, argv[i]+end)) set = 1; } else { exit_code=1; fprintf(stderr, " Unknown condition: %s\n", argv[i]); } } (*start) = i; return set; }
extern int sacctmgr_modify_qos(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_qos_cond_t *qos_cond = xmalloc(sizeof(slurmdb_qos_cond_t)); slurmdb_qos_rec_t *qos = xmalloc(sizeof(slurmdb_qos_rec_t)); int i=0; int cond_set = 0, rec_set = 0, set = 0; List ret_list = NULL; slurmdb_init_qos_rec(qos, 0); for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5))) { i++; cond_set += _set_cond(&i, argc, argv, qos_cond, NULL); } else if (!strncasecmp (argv[i], "Set", MAX(command_len, 3))) { i++; rec_set += _set_rec(&i, argc, argv, NULL, qos); } else { cond_set += _set_cond(&i, argc, argv, qos_cond, NULL); } } if (exit_code) { slurmdb_destroy_qos_cond(qos_cond); slurmdb_destroy_qos_rec(qos); return SLURM_ERROR; } else if (!rec_set) { exit_code=1; fprintf(stderr, " You didn't give me anything to set\n"); slurmdb_destroy_qos_cond(qos_cond); slurmdb_destroy_qos_rec(qos); return SLURM_ERROR; } else if (!cond_set) { if (!commit_check("You didn't set any conditions with 'WHERE'.\n" "Are you sure you want to continue?")) { printf("Aborted\n"); slurmdb_destroy_qos_cond(qos_cond); slurmdb_destroy_qos_rec(qos); return SLURM_SUCCESS; } } notice_thread_init(); ret_list = acct_storage_g_modify_qos(db_conn, my_uid, qos_cond, qos); if (ret_list && list_count(ret_list)) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); printf(" Modified qos...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); set = 1; } else if (ret_list) { printf(" Nothing modified\n"); rc = SLURM_ERROR; } else { exit_code=1; fprintf(stderr, " Error with request: %s\n", slurm_strerror(errno)); rc = SLURM_ERROR; } if (ret_list) list_destroy(ret_list); notice_thread_fini(); if (set) { if (commit_check("Would you like to commit changes?")) acct_storage_g_commit(db_conn, 1); else { printf(" Changes Discarded\n"); acct_storage_g_commit(db_conn, 0); } } slurmdb_destroy_qos_cond(qos_cond); slurmdb_destroy_qos_rec(qos); return rc; }
/* Attempt to schedule a specific job on specific available nodes * IN job_ptr - job to schedule * IN/OUT avail_bitmap - nodes available/selected to use * IN exc_core_bitmap - cores which can not be used * RET SLURM_SUCCESS on success, otherwise an error code */ static int _try_sched(struct job_record *job_ptr, bitstr_t **avail_bitmap, uint32_t min_nodes, uint32_t max_nodes, uint32_t req_nodes, bitstr_t *exc_core_bitmap) { bitstr_t *tmp_bitmap; int rc = SLURM_SUCCESS; int feat_cnt = _num_feature_count(job_ptr); List preemptee_candidates = NULL; if (feat_cnt) { /* Ideally schedule the job feature by feature, * but I don't want to add that complexity here * right now, so clear the feature counts and try * to schedule. This will work if there is only * one feature count. It should work fairly well * in cases where there are multiple feature * counts. */ struct job_details *detail_ptr = job_ptr->details; ListIterator feat_iter; struct feature_record *feat_ptr; int i = 0, list_size; uint16_t *feat_cnt_orig = NULL, high_cnt = 0; /* Clear the feature counts */ list_size = list_count(detail_ptr->feature_list); feat_cnt_orig = xmalloc(sizeof(uint16_t) * list_size); feat_iter = list_iterator_create(detail_ptr->feature_list); while ((feat_ptr = (struct feature_record *) list_next(feat_iter))) { high_cnt = MAX(high_cnt, feat_ptr->count); feat_cnt_orig[i++] = feat_ptr->count; feat_ptr->count = 0; } list_iterator_destroy(feat_iter); if ((job_req_node_filter(job_ptr, *avail_bitmap) != SLURM_SUCCESS) || (bit_set_count(*avail_bitmap) < high_cnt)) { rc = ESLURM_NODES_BUSY; } else { preemptee_candidates = slurm_find_preemptable_jobs(job_ptr); rc = select_g_job_test(job_ptr, *avail_bitmap, high_cnt, max_nodes, req_nodes, SELECT_MODE_WILL_RUN, preemptee_candidates, NULL, exc_core_bitmap); } /* Restore the feature counts */ i = 0; feat_iter = list_iterator_create(detail_ptr->feature_list); while ((feat_ptr = (struct feature_record *) list_next(feat_iter))) { feat_ptr->count = feat_cnt_orig[i++]; } list_iterator_destroy(feat_iter); xfree(feat_cnt_orig); } else { /* Try to schedule the job. First on dedicated nodes * then on shared nodes (if so configured). */ uint16_t orig_shared; time_t now = time(NULL); char str[100]; preemptee_candidates = slurm_find_preemptable_jobs(job_ptr); orig_shared = job_ptr->details->shared; job_ptr->details->shared = 0; tmp_bitmap = bit_copy(*avail_bitmap); if (exc_core_bitmap) { bit_fmt(str, (sizeof(str) - 1), exc_core_bitmap); debug2(" _try_sched with exclude core bitmap: %s",str); } rc = select_g_job_test(job_ptr, *avail_bitmap, min_nodes, max_nodes, req_nodes, SELECT_MODE_WILL_RUN, preemptee_candidates, NULL, exc_core_bitmap); job_ptr->details->shared = orig_shared; if (((rc != SLURM_SUCCESS) || (job_ptr->start_time > now)) && (orig_shared != 0)) { FREE_NULL_BITMAP(*avail_bitmap); *avail_bitmap= tmp_bitmap; rc = select_g_job_test(job_ptr, *avail_bitmap, min_nodes, max_nodes, req_nodes, SELECT_MODE_WILL_RUN, preemptee_candidates, NULL, exc_core_bitmap); } else FREE_NULL_BITMAP(tmp_bitmap); } if (preemptee_candidates) list_destroy(preemptee_candidates); return rc; }
/* Perform job initiation work */ static void _start_agent(bg_action_t *bg_action_ptr) { int rc, set_user_rc = SLURM_SUCCESS; bg_record_t *bg_record = NULL; bg_record_t *found_record = NULL; ListIterator itr; List delete_list = NULL; int requeue_job = 0; uint32_t req_job_id = bg_action_ptr->job_ptr->job_id; bool block_inited = 0; bool delete_it = 0; slurm_mutex_lock(&block_state_mutex); bg_record = find_bg_record_in_list(bg_lists->main, bg_action_ptr->bg_block_id); if (!bg_record) { bg_record->modifying = 0; slurm_mutex_unlock(&block_state_mutex); error("block %s not found in bg_lists->main", bg_action_ptr->bg_block_id); bg_requeue_job(req_job_id, 1, 0); return; } if ((bg_record->job_running <= NO_JOB_RUNNING) && !find_job_in_bg_record(bg_record, req_job_id)) { bg_record->modifying = 0; // bg_reset_block(bg_record); should already happened slurm_mutex_unlock(&block_state_mutex); debug("job %u finished during the queueing job " "(everything is ok)", req_job_id); return; } if ((bg_record->state == BG_BLOCK_TERM) || bg_record->free_cnt) { /* It doesn't appear state of a small block (conn_type) is held on a BGP system so if we to reset it so, just set the reboot flag and handle it later in that code. */ bg_action_ptr->reboot = 1; } delete_list = list_create(NULL); itr = list_iterator_create(bg_lists->main); while ((found_record = list_next(itr))) { if (bg_record == found_record) continue; if (!blocks_overlap(bg_record, found_record)) { debug2("block %s isn't part of %s", found_record->bg_block_id, bg_record->bg_block_id); continue; } if (found_record->job_ptr || (found_record->job_list && list_count(found_record->job_list))) { struct job_record *job_ptr = found_record->job_ptr; if (!found_record->job_ptr) job_ptr = find_job_in_bg_record( found_record, NO_VAL); error("Trying to start job %u on block %s, " "but there is a job %u running on an overlapping " "block %s it will not end until %ld. " "This should never happen.", req_job_id, bg_record->bg_block_id, job_ptr->job_id, found_record->bg_block_id, job_ptr->end_time); requeue_job = 1; break; } debug2("need to make sure %s is free, it's part of %s", found_record->bg_block_id, bg_record->bg_block_id); list_push(delete_list, found_record); } list_iterator_destroy(itr); if (requeue_job) { list_destroy(delete_list); bg_reset_block(bg_record, bg_action_ptr->job_ptr); bg_record->modifying = 0; slurm_mutex_unlock(&block_state_mutex); bg_requeue_job(req_job_id, 0, 0); return; } slurm_mutex_unlock(&block_state_mutex); if (bg_conf->layout_mode == LAYOUT_DYNAMIC) delete_it = 1; rc = free_block_list(req_job_id, delete_list, delete_it, 1); list_destroy(delete_list); if (rc != SLURM_SUCCESS) { error("Problem with deallocating blocks to run job %u " "on block %s", req_job_id, bg_action_ptr->bg_block_id); slurm_mutex_lock(&block_state_mutex); /* Failure will unlock block_state_mutex so no need to unlock before return. No need to reset modifying here if the block doesn't exist. */ if (_make_sure_block_still_exists(bg_action_ptr, bg_record)) { bg_record->modifying = 0; slurm_mutex_unlock(&block_state_mutex); } if (IS_JOB_CONFIGURING(bg_action_ptr->job_ptr)) bg_requeue_job(req_job_id, 0, 0); return; } while (1) { slurm_mutex_lock(&block_state_mutex); /* Failure will unlock block_state_mutex so no need to unlock before return. No need to reset modifying here if the block doesn't exist. */ if (!_make_sure_block_still_exists(bg_action_ptr, bg_record)) return; /* If another thread is freeing this block we need to wait until it is done or we will get into a state where this job will be killed. */ if (!bg_record->free_cnt) break; debug("Waiting for block %s to free for job %u. " "%d thread(s) trying to free it", bg_record->bg_block_id, req_job_id, bg_record->free_cnt); slurm_mutex_unlock(&block_state_mutex); sleep(1); } /* This was set in the start_job function to close the above window where a job could be mistakenly requeued if another thread is trying to free this block as we are trying to run on it, which is fine since we will reboot it later. */ bg_record->modifying = 0; if ((bg_record->job_running <= NO_JOB_RUNNING) && !find_job_in_bg_record(bg_record, req_job_id)) { // bg_reset_block(bg_record); should already happened slurm_mutex_unlock(&block_state_mutex); debug("job %u already finished before boot", req_job_id); return; } if (bg_record->job_list && (bg_action_ptr->job_ptr->total_cpus != bg_record->cpu_cnt) && (list_count(bg_record->job_list) != 1)) { /* We don't allow modification of a block or reboot of a block if we are running multiple jobs on the block. */ debug2("no reboot"); goto no_reboot; } rc = 0; #ifdef HAVE_BGL if (bg_action_ptr->blrtsimage && strcasecmp(bg_action_ptr->blrtsimage, bg_record->blrtsimage)) { debug3("changing BlrtsImage from %s to %s", bg_record->blrtsimage, bg_action_ptr->blrtsimage); xfree(bg_record->blrtsimage); bg_record->blrtsimage = xstrdup(bg_action_ptr->blrtsimage); rc = 1; } #elif defined HAVE_BGP if ((bg_action_ptr->conn_type[0] >= SELECT_SMALL) && (bg_action_ptr->conn_type[0] != bg_record->conn_type[0])) { if (bg_conf->slurm_debug_level >= LOG_LEVEL_DEBUG3) { char *req_conn_type = conn_type_string_full(bg_action_ptr->conn_type); char *conn_type = conn_type_string_full(bg_record->conn_type); debug3("changing small block mode from %s to %s", conn_type, req_conn_type); xfree(req_conn_type); xfree(conn_type); } rc = 1; # ifndef HAVE_BG_FILES /* since we don't check state on an emulated system we * have to change it here */ bg_record->conn_type[0] = bg_action_ptr->conn_type[0]; # endif } #endif #ifdef HAVE_BG_L_P if (bg_action_ptr->linuximage && strcasecmp(bg_action_ptr->linuximage, bg_record->linuximage)) { # ifdef HAVE_BGL debug3("changing LinuxImage from %s to %s", bg_record->linuximage, bg_action_ptr->linuximage); # else debug3("changing CnloadImage from %s to %s", bg_record->linuximage, bg_action_ptr->linuximage); # endif xfree(bg_record->linuximage); bg_record->linuximage = xstrdup(bg_action_ptr->linuximage); rc = 1; } if (bg_action_ptr->ramdiskimage && strcasecmp(bg_action_ptr->ramdiskimage, bg_record->ramdiskimage)) { # ifdef HAVE_BGL debug3("changing RamDiskImage from %s to %s", bg_record->ramdiskimage, bg_action_ptr->ramdiskimage); # else debug3("changing IoloadImage from %s to %s", bg_record->ramdiskimage, bg_action_ptr->ramdiskimage); # endif xfree(bg_record->ramdiskimage); bg_record->ramdiskimage = xstrdup(bg_action_ptr->ramdiskimage); rc = 1; } #endif if (bg_action_ptr->mloaderimage && strcasecmp(bg_action_ptr->mloaderimage, bg_record->mloaderimage)) { debug3("changing MloaderImage from %s to %s", bg_record->mloaderimage, bg_action_ptr->mloaderimage); xfree(bg_record->mloaderimage); bg_record->mloaderimage = xstrdup(bg_action_ptr->mloaderimage); rc = 1; } if (rc || bg_action_ptr->reboot) { bg_record->modifying = 1; /* Increment free_cnt to make sure we don't loose this * block since bg_free_block will unlock block_state_mutex. */ bg_record->free_cnt++; bg_free_block(bg_record, 1, 1); bg_record->free_cnt--; #if defined HAVE_BG_FILES && defined HAVE_BG_L_P #ifdef HAVE_BGL if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_BlrtsImg, bg_record->blrtsimage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_BlrtsImg): %s", bg_err_str(rc)); if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_LinuxImg, bg_record->linuximage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_LinuxImg): %s", bg_err_str(rc)); if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_RamdiskImg, bg_record->ramdiskimage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_RamdiskImg): %s", bg_err_str(rc)); #elif defined HAVE_BGP if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_CnloadImg, bg_record->linuximage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_CnloadImg): %s", bg_err_str(rc)); if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_IoloadImg, bg_record->ramdiskimage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_IoloadImg): %s", bg_err_str(rc)); if (bg_action_ptr->conn_type[0] > SELECT_SMALL) { char *conn_type = NULL; switch(bg_action_ptr->conn_type[0]) { case SELECT_HTC_S: conn_type = "s"; break; case SELECT_HTC_D: conn_type = "d"; break; case SELECT_HTC_V: conn_type = "v"; break; case SELECT_HTC_L: conn_type = "l"; break; default: break; } /* the option has to be set before the pool can be set */ if ((rc = bridge_block_modify( bg_record->bg_block_id, RM_MODIFY_Options, conn_type)) != SLURM_SUCCESS) error("bridge_set_data(RM_MODIFY_Options): %s", bg_err_str(rc)); } #endif if ((rc = bridge_block_modify(bg_record->bg_block_id, RM_MODIFY_MloaderImg, bg_record->mloaderimage)) != SLURM_SUCCESS) error("bridge_block_modify(RM_MODIFY_MloaderImg): %s", bg_err_str(rc)); #endif bg_record->modifying = 0; } no_reboot: if (bg_record->state == BG_BLOCK_FREE) { if ((rc = bridge_block_boot(bg_record)) != SLURM_SUCCESS) { char reason[200]; bg_record->boot_state = 0; bg_record->boot_count = 0; if (rc == BG_ERROR_INVALID_STATE) snprintf(reason, sizeof(reason), "Block %s is in an incompatible " "state. This usually means " "hardware is allocated " "by another block (maybe outside " "of SLURM).", bg_record->bg_block_id); else snprintf(reason, sizeof(reason), "Couldn't boot block %s: %s", bg_record->bg_block_id, bg_err_str(rc)); slurm_mutex_unlock(&block_state_mutex); requeue_and_error(bg_record, reason); return; } } else if (bg_record->state == BG_BLOCK_BOOTING) { #ifdef HAVE_BG_FILES bg_record->boot_state = 1; #else if (!block_ptr_exist_in_list(bg_lists->booted, bg_record)) list_push(bg_lists->booted, bg_record); bg_record->state = BG_BLOCK_INITED; last_bg_update = time(NULL); #endif } if ((bg_record->job_running <= NO_JOB_RUNNING) && !find_job_in_bg_record(bg_record, req_job_id)) { slurm_mutex_unlock(&block_state_mutex); debug("job %u finished during the start of the boot " "(everything is ok)", req_job_id); return; } /* Don't reset boot_count, it will be reset when state changes, and needs to outlast a job allocation. */ /* bg_record->boot_count = 0; */ if (bg_record->state == BG_BLOCK_INITED) { debug("block %s is already ready.", bg_record->bg_block_id); /* Just in case reset the boot flags */ bg_record->boot_state = 0; bg_record->boot_count = 0; set_user_rc = bridge_block_sync_users(bg_record); block_inited = 1; } slurm_mutex_unlock(&block_state_mutex); /* This lock needs to happen after the block_state_mutex to avoid deadlock. */ if (block_inited && bg_action_ptr->job_ptr) { slurmctld_lock_t job_write_lock = { NO_LOCK, WRITE_LOCK, NO_LOCK, NO_LOCK }; lock_slurmctld(job_write_lock); bg_action_ptr->job_ptr->job_state &= (~JOB_CONFIGURING); last_job_update = time(NULL); unlock_slurmctld(job_write_lock); } if (set_user_rc == SLURM_ERROR) { sleep(2); /* wait for the slurmd to begin the batch script, slurm_fail_job() is a no-op if issued prior to the script initiation do clean up just incase the fail job isn't ran */ (void) slurm_fail_job(req_job_id); } }
extern List mysql_jobcomp_process_get_jobs(slurmdb_job_cond_t *job_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; char *selected_part = NULL; slurmdb_selected_step_t *selected_step = NULL; ListIterator itr = NULL; int set = 0; MYSQL_RES *result = NULL; MYSQL_ROW row; int i; int lc = 0; jobcomp_job_rec_t *job = NULL; char time_str[32]; time_t temp_time; List job_list = list_create(jobcomp_destroy_job); if (job_cond->step_list && list_count(job_cond->step_list)) { set = 0; xstrcat(extra, " where ("); itr = list_iterator_create(job_cond->step_list); while((selected_step = list_next(itr))) { if (set) xstrcat(extra, " || "); tmp = xstrdup_printf("jobid=%d", selected_step->jobid); xstrcat(extra, tmp); set = 1; xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (job_cond->partition_list && list_count(job_cond->partition_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); itr = list_iterator_create(job_cond->partition_list); while((selected_part = list_next(itr))) { if (set) xstrcat(extra, " || "); tmp = xstrdup_printf("`partition`='%s'", selected_part); xstrcat(extra, tmp); set = 1; xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } i = 0; while(jobcomp_table_fields[i].name) { if (i) xstrcat(tmp, ", "); xstrcat(tmp, jobcomp_table_fields[i].name); i++; } query = xstrdup_printf("select %s from %s", tmp, jobcomp_table); xfree(tmp); if (extra) { xstrcat(query, extra); xfree(extra); } //info("query = %s", query); if (!(result = mysql_db_query_ret(jobcomp_mysql_conn, query, 0))) { xfree(query); list_destroy(job_list); return NULL; } xfree(query); while((row = mysql_fetch_row(result))) { lc++; job = xmalloc(sizeof(jobcomp_job_rec_t)); if (row[JOBCOMP_REQ_JOBID]) job->jobid = slurm_atoul(row[JOBCOMP_REQ_JOBID]); job->partition = xstrdup(row[JOBCOMP_REQ_PARTITION]); temp_time = atoi(row[JOBCOMP_REQ_STARTTIME]); slurm_make_time_str(&temp_time, time_str, sizeof(time_str)); job->start_time = xstrdup(time_str); temp_time = atoi(row[JOBCOMP_REQ_ENDTIME]); slurm_make_time_str(&temp_time, time_str, sizeof(time_str)); job->elapsed_time = atoi(row[JOBCOMP_REQ_ENDTIME]) - atoi(row[JOBCOMP_REQ_STARTTIME]); job->end_time = xstrdup(time_str); if (row[JOBCOMP_REQ_UID]) job->uid = slurm_atoul(row[JOBCOMP_REQ_UID]); job->uid_name = xstrdup(row[JOBCOMP_REQ_USER_NAME]); if (row[JOBCOMP_REQ_GID]) job->gid = slurm_atoul(row[JOBCOMP_REQ_GID]); job->gid_name = xstrdup(row[JOBCOMP_REQ_GROUP_NAME]); job->jobname = xstrdup(row[JOBCOMP_REQ_NAME]); job->nodelist = xstrdup(row[JOBCOMP_REQ_NODELIST]); if (row[JOBCOMP_REQ_NODECNT]) job->node_cnt = slurm_atoul(row[JOBCOMP_REQ_NODECNT]); if (row[JOBCOMP_REQ_STATE]) { i = atoi(row[JOBCOMP_REQ_STATE]); job->state = xstrdup(job_state_string(i)); } job->timelimit = xstrdup(row[JOBCOMP_REQ_TIMELIMIT]); if (row[JOBCOMP_REQ_MAXPROCS]) job->max_procs = slurm_atoul(row[JOBCOMP_REQ_MAXPROCS]); job->connection = xstrdup(row[JOBCOMP_REQ_CONNECTION]); job->reboot = xstrdup(row[JOBCOMP_REQ_REBOOT]); job->rotate = xstrdup(row[JOBCOMP_REQ_ROTATE]); job->geo = xstrdup(row[JOBCOMP_REQ_GEOMETRY]); job->bg_start_point = xstrdup(row[JOBCOMP_REQ_START]); job->blockid = xstrdup(row[JOBCOMP_REQ_BLOCKID]); list_append(job_list, job); } mysql_free_result(result); return job_list; }
extern void get_info_resv(GtkTable *table, display_data_t *display_data) { int error_code = SLURM_SUCCESS; List info_list = NULL; static int view = -1; static reserve_info_msg_t *resv_info_ptr = NULL; char error_char[100]; GtkWidget *label = NULL; GtkTreeView *tree_view = NULL; static GtkWidget *display_widget = NULL; int j=0; ListIterator itr = NULL; sview_resv_info_t *sview_resv_info_ptr = NULL; reserve_info_t *resv_ptr = NULL; time_t now = time(NULL); GtkTreePath *path = NULL; static bool set_opts = FALSE; if (!set_opts) set_page_opts(RESV_PAGE, display_data_resv, SORTID_CNT, _initial_page_opts); set_opts = TRUE; /* reset */ if (!table && !display_data) { if (display_widget) gtk_widget_destroy(display_widget); display_widget = NULL; resv_info_ptr = NULL; goto reset_curs; } if (display_data) local_display_data = display_data; if (!table) { display_data_resv->set_menu = local_display_data->set_menu; goto reset_curs; } if (display_widget && toggled) { gtk_widget_destroy(display_widget); display_widget = NULL; goto display_it; } error_code = get_new_info_resv(&resv_info_ptr, force_refresh); if (error_code == SLURM_NO_CHANGE_IN_DATA) { } else if (error_code != SLURM_SUCCESS) { if (view == ERROR_VIEW) goto end_it; if (display_widget) gtk_widget_destroy(display_widget); view = ERROR_VIEW; sprintf(error_char, "slurm_load_reservations: %s", slurm_strerror(slurm_get_errno())); label = gtk_label_new(error_char); gtk_table_attach_defaults(table, label, 0, 1, 0, 1); gtk_widget_show(label); display_widget = gtk_widget_ref(GTK_WIDGET(label)); goto end_it; } display_it: info_list = _create_resv_info_list(resv_info_ptr); if (!info_list) goto reset_curs; /* set up the grid */ if (display_widget && GTK_IS_TREE_VIEW(display_widget) && gtk_tree_selection_count_selected_rows( gtk_tree_view_get_selection( GTK_TREE_VIEW(display_widget)))) { GtkTreeViewColumn *focus_column = NULL; /* highlight the correct nodes from the last selection */ gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget), &path, &focus_column); } if (!path) { itr = list_iterator_create(info_list); while ((sview_resv_info_ptr = list_next(itr))) { resv_ptr = sview_resv_info_ptr->resv_ptr; if ((resv_ptr->start_time > now) || (resv_ptr->end_time < now)) continue;/* only map current reservations */ j=0; while (resv_ptr->node_inx[j] >= 0) { change_grid_color(grid_button_list, resv_ptr->node_inx[j], resv_ptr->node_inx[j+1], sview_resv_info_ptr-> color_inx, true, 0); j += 2; } } list_iterator_destroy(itr); change_grid_color(grid_button_list, -1, -1, MAKE_WHITE, true, 0); } else highlight_grid(GTK_TREE_VIEW(display_widget), SORTID_NODE_INX, SORTID_COLOR_INX, grid_button_list); if (view == ERROR_VIEW && display_widget) { gtk_widget_destroy(display_widget); display_widget = NULL; } if (!display_widget) { tree_view = create_treeview(local_display_data, &grid_button_list); gtk_tree_selection_set_mode( gtk_tree_view_get_selection(tree_view), GTK_SELECTION_MULTIPLE); display_widget = gtk_widget_ref(GTK_WIDGET(tree_view)); gtk_table_attach_defaults(table, GTK_WIDGET(tree_view), 0, 1, 0, 1); /* since this function sets the model of the tree_view to the treestore we don't really care about the return value */ create_treestore(tree_view, display_data_resv, SORTID_CNT, SORTID_TIME_START, SORTID_COLOR); } view = INFO_VIEW; _update_info_resv(info_list, GTK_TREE_VIEW(display_widget)); end_it: toggled = FALSE; force_refresh = FALSE; reset_curs: if (main_window && main_window->window) gdk_window_set_cursor(main_window->window, NULL); return; }
extern int sacctmgr_delete_qos(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_qos_cond_t *qos_cond = xmalloc(sizeof(slurmdb_qos_cond_t)); int i=0; List ret_list = NULL; int set = 0; for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5)) || !strncasecmp (argv[i], "Set", MAX(command_len, 3))) i++; set += _set_cond(&i, argc, argv, qos_cond, NULL); } if (!set) { exit_code=1; fprintf(stderr, " No conditions given to remove, not executing.\n"); slurmdb_destroy_qos_cond(qos_cond); return SLURM_ERROR; } else if (set == -1) { slurmdb_destroy_qos_cond(qos_cond); return SLURM_ERROR; } if (!g_qos_list) g_qos_list = acct_storage_g_get_qos( db_conn, my_uid, NULL); notice_thread_init(); ret_list = acct_storage_g_remove_qos(db_conn, my_uid, qos_cond); notice_thread_fini(); slurmdb_destroy_qos_cond(qos_cond); if (ret_list && list_count(ret_list)) { char *object = NULL; ListIterator itr = NULL; /* Check to see if person is trying to remove a default * qos of an association. _isdefault only works with the * output from acct_storage_g_remove_qos, and * with a previously got g_qos_list. */ if (_isdefault(ret_list)) { exit_code=1; fprintf(stderr, " Please either remove the qos' listed " "above from list and resubmit,\n" " or change the default qos to " "remove the qos.\n" " Changes Discarded\n"); acct_storage_g_commit(db_conn, 0); goto end_it; } itr = list_iterator_create(ret_list); printf(" Deleting QOS(s)...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); if (commit_check("Would you like to commit changes?")) { acct_storage_g_commit(db_conn, 1); } else { printf(" Changes Discarded\n"); acct_storage_g_commit(db_conn, 0); } } else if (ret_list) { printf(" Nothing deleted\n"); rc = SLURM_ERROR; } else { exit_code=1; fprintf(stderr, " Error with request: %s\n", slurm_strerror(errno)); rc = SLURM_ERROR; } end_it: if (ret_list) list_destroy(ret_list); return rc; }
extern void popup_all_resv(GtkTreeModel *model, GtkTreeIter *iter, int id) { char *name = NULL; char title[100]; ListIterator itr = NULL; popup_info_t *popup_win = NULL; GError *error = NULL; gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1); switch(id) { case PART_PAGE: snprintf(title, 100, "Partition(s) with reservation %s", name); break; case JOB_PAGE: snprintf(title, 100, "Job(s) in reservation %s", name); break; case NODE_PAGE: if (cluster_flags & CLUSTER_FLAG_BG) snprintf(title, 100, "Midplane(s) in reservation %s", name); else snprintf(title, 100, "Node(s) in reservation %s ", name); break; case BLOCK_PAGE: snprintf(title, 100, "Block(s) in reservation %s", name); break; case SUBMIT_PAGE: snprintf(title, 100, "Submit job in reservation %s", name); break; case INFO_PAGE: snprintf(title, 100, "Full info for reservation %s", name); break; default: g_print("resv got %d\n", id); } itr = list_iterator_create(popup_list); while ((popup_win = list_next(itr))) { if (popup_win->spec_info) if (!strcmp(popup_win->spec_info->title, title)) { break; } } list_iterator_destroy(itr); if (!popup_win) { if (id == INFO_PAGE) popup_win = create_popup_info(id, RESV_PAGE, title); else popup_win = create_popup_info(RESV_PAGE, id, title); } else { g_free(name); gtk_window_present(GTK_WINDOW(popup_win->popup)); return; } /* Pass the model and the structs from the iter so we can always get the current node_inx. */ popup_win->model = model; popup_win->iter = *iter; popup_win->node_inx_id = SORTID_NODE_INX; switch(id) { case JOB_PAGE: case INFO_PAGE: popup_win->spec_info->search_info->gchar_data = name; //specific_info_job(popup_win); break; case BLOCK_PAGE: case NODE_PAGE: case PART_PAGE: g_free(name); gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1); popup_win->spec_info->search_info->gchar_data = name; popup_win->spec_info->search_info->search_type = SEARCH_NODE_NAME; //specific_info_node(popup_win); break; case SUBMIT_PAGE: break; default: g_print("resv got unknown type %d\n", id); } if (!sview_thread_new((gpointer)popup_thr, popup_win, FALSE, &error)) { g_printerr ("Failed to create resv popup thread: %s\n", error->message); return; } }
static int _set_cond(int *start, int argc, char *argv[], slurmdb_qos_cond_t *qos_cond, List format_list) { int i; int set = 0; int end = 0; int command_len = 0; if (!qos_cond) { error("No qos_cond given"); return -1; } for (i=(*start); i<argc; i++) { end = parse_option_end(argv[i]); if (!end) command_len=strlen(argv[i]); else { command_len=end-1; if (argv[i][end] == '=') { end++; } } if (!strncasecmp (argv[i], "Set", MAX(command_len, 3))) { i--; break; } else if (!end && !strncasecmp (argv[i], "WithDeleted", MAX(command_len, 5))) { qos_cond->with_deleted = 1; } else if (!end && !strncasecmp(argv[i], "where", MAX(command_len, 5))) { continue; } else if (!end || !strncasecmp (argv[i], "Names", MAX(command_len, 1)) || !strncasecmp (argv[i], "QOSLevel", MAX(command_len, 1))) { if (!qos_cond->name_list) { qos_cond->name_list = list_create(slurm_destroy_char); } if (slurm_addto_char_list(qos_cond->name_list, argv[i]+end)) set = 1; } else if (!strncasecmp (argv[i], "Descriptions", MAX(command_len, 1))) { if (!qos_cond->description_list) { qos_cond->description_list = list_create(slurm_destroy_char); } if (slurm_addto_char_list(qos_cond->description_list, argv[i]+end)) set = 1; } else if (!strncasecmp (argv[i], "Format", MAX(command_len, 1))) { if (format_list) slurm_addto_char_list(format_list, argv[i]+end); } else if (!strncasecmp (argv[i], "Ids", MAX(command_len, 1))) { ListIterator itr = NULL; char *temp = NULL; uint32_t id = 0; if (!qos_cond->id_list) { qos_cond->id_list = list_create(slurm_destroy_char); } if (slurm_addto_char_list(qos_cond->id_list, argv[i]+end)) set = 1; /* check to make sure user gave ints here */ itr = list_iterator_create(qos_cond->id_list); while ((temp = list_next(itr))) { if (get_uint(temp, &id, "QOS ID") != SLURM_SUCCESS) { exit_code = 1; list_delete_item(itr); } } list_iterator_destroy(itr); } else if (!strncasecmp (argv[i], "PreemptMode", MAX(command_len, 8))) { if (!qos_cond) continue; qos_cond->preempt_mode |= _parse_preempt_modes(argv[i]+end); if (qos_cond->preempt_mode == (uint16_t)NO_VAL) { fprintf(stderr, " Bad Preempt Mode given: %s\n", argv[i]); exit_code = 1; } else if (qos_cond->preempt_mode == PREEMPT_MODE_SUSPEND) { printf("PreemptType and PreemptMode " "values incompatible\n"); exit_code = 1; } else set = 1; } else { exit_code=1; fprintf(stderr, " Unknown condition: %s\n" " Use keyword 'set' to modify " "SLURM_PRINT_VALUE\n", argv[i]); } } (*start) = i; return set; }
static void _display_info_resv(List info_list, popup_info_t *popup_win) { specific_info_t *spec_info = popup_win->spec_info; char *name = (char *)spec_info->search_info->gchar_data; int found = 0; reserve_info_t *resv_ptr = NULL; GtkTreeView *treeview = NULL; ListIterator itr = NULL; sview_resv_info_t *sview_resv_info = NULL; int update = 0; int j = 0; if (!spec_info->search_info->gchar_data) { //info = xstrdup("No pointer given!"); goto finished; } need_refresh: if (!spec_info->display_widget) { treeview = create_treeview_2cols_attach_to_table( popup_win->table); spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(treeview)); } else { treeview = GTK_TREE_VIEW(spec_info->display_widget); update = 1; } itr = list_iterator_create(info_list); while ((sview_resv_info = (sview_resv_info_t*) list_next(itr))) { resv_ptr = sview_resv_info->resv_ptr; if (!strcmp(resv_ptr->name, name)) { j=0; while (resv_ptr->node_inx[j] >= 0) { change_grid_color( popup_win->grid_button_list, resv_ptr->node_inx[j], resv_ptr->node_inx[j+1], sview_resv_info->color_inx, true, 0); j += 2; } _layout_resv_record(treeview, sview_resv_info, update); found = 1; break; } } list_iterator_destroy(itr); post_setup_popup_grid_list(popup_win); if (!found) { if (!popup_win->not_found) { char *temp = "RESERVATION DOESN'T EXSIST\n"; GtkTreeIter iter; GtkTreeModel *model = NULL; /* only time this will be run so no update */ model = gtk_tree_view_get_model(treeview); add_display_treestore_line(0, GTK_TREE_STORE(model), &iter, temp, ""); } popup_win->not_found = true; } else { if (popup_win->not_found) { popup_win->not_found = false; gtk_widget_destroy(spec_info->display_widget); goto need_refresh; } } gtk_widget_show(spec_info->display_widget); finished: return; }
static bool _isdefault(List qos_list) { int rc = 0; slurmdb_association_cond_t assoc_cond; slurmdb_association_rec_t *assoc = NULL; ListIterator itr; List ret_list = NULL; char *name = NULL; if (!qos_list || !list_count(qos_list)) return rc; /* this needs to happen before any removing takes place so we can figure out things correctly */ xassert(g_qos_list); memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); assoc_cond.without_parent_info = 1; assoc_cond.def_qos_id_list = list_create(slurm_destroy_char); itr = list_iterator_create(qos_list); while ((name = list_next(itr))) { uint32_t id = str_2_slurmdb_qos(g_qos_list, name); if (id == NO_VAL) continue; list_append(assoc_cond.def_qos_id_list, xstrdup_printf("%u", id)); } list_iterator_destroy(itr); ret_list = acct_storage_g_get_associations( db_conn, my_uid, &assoc_cond); list_destroy(assoc_cond.def_qos_id_list); if (!ret_list || !list_count(ret_list)) goto end_it; fprintf(stderr," Associations listed below have these " "as their Default QOS.\n"); itr = list_iterator_create(ret_list); while((assoc = list_next(itr))) { name = slurmdb_qos_str(g_qos_list, assoc->def_qos_id); if (!assoc->user) { // see if this isn't a user fprintf(stderr, " DefQOS = %-10s C = %-10s A = %-20s\n", name, assoc->cluster, assoc->acct); } else if (assoc->partition) { // see if there is a partition name fprintf(stderr, " DefQOS = %-10s C = %-10s A = %-20s " "U = %-9s P = %s\n", name, assoc->cluster, assoc->acct, assoc->user, assoc->partition); } else { fprintf(stderr, " DefQOS = %-10s C = %-10s A = %-20s " "U = %-9s\n", name, assoc->cluster, assoc->acct, assoc->user); } } list_iterator_destroy(itr); rc = 1; end_it: if (ret_list) list_destroy(ret_list); return rc; }
/* This needs to happen to make since 2.1 code doesn't have enough * smarts to figure out it isn't adding a default wckey if just * adding a new wckey for a user that has never been on the cluster before. */ static int _make_sure_users_have_default( mysql_conn_t *mysql_conn, List user_list) { char *query = NULL, *cluster = NULL, *user = NULL; ListIterator itr = NULL, clus_itr = NULL; int rc = SLURM_SUCCESS; if (!user_list) return SLURM_SUCCESS; slurm_mutex_lock(&as_mysql_cluster_list_lock); clus_itr = list_iterator_create(as_mysql_cluster_list); itr = list_iterator_create(user_list); while ((user = list_next(itr))) { while ((cluster = list_next(clus_itr))) { MYSQL_RES *result = NULL; MYSQL_ROW row; char *wckey = NULL; /* only look at non * and non deleted ones */ query = xstrdup_printf( "select distinct is_def, wckey_name from " "\"%s_%s\" where user='******' and wckey_name " "not like '*%%' and deleted=0 FOR UPDATE;", cluster, wckey_table, user); debug4("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); error("couldn't query the database"); rc = SLURM_ERROR; break; } xfree(query); /* Check to see if the user is even added to the cluster. */ if (!mysql_num_rows(result)) { mysql_free_result(result); continue; } while ((row = mysql_fetch_row(result))) { if (row[0][0] == '1') break; if (!wckey) wckey = xstrdup(row[1]); } mysql_free_result(result); /* we found one so just continue */ if (row || !wckey) { xfree(wckey); continue; } query = xstrdup_printf( "update \"%s_%s\" set is_def=1 where " "user='******' and wckey_name='%s';", cluster, wckey_table, user, wckey); xfree(wckey); if (debug_flags & DEBUG_FLAG_DB_WCKEY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); rc = mysql_db_query(mysql_conn, query); xfree(query); if (rc != SLURM_SUCCESS) { error("problem with update query"); rc = SLURM_ERROR; break; } } if (!rc != SLURM_SUCCESS) break; list_iterator_reset(clus_itr); } list_iterator_destroy(itr); list_iterator_destroy(clus_itr); slurm_mutex_unlock(&as_mysql_cluster_list_lock); return rc; }
extern int sacctmgr_add_qos(int argc, char *argv[]) { int rc = SLURM_SUCCESS; int i=0, limit_set=0; ListIterator itr = NULL; slurmdb_qos_rec_t *qos = NULL; slurmdb_qos_rec_t *start_qos = xmalloc(sizeof(slurmdb_qos_rec_t)); List name_list = list_create(slurm_destroy_char); char *description = NULL; char *name = NULL; List qos_list = NULL; char *qos_str = NULL; slurmdb_init_qos_rec(start_qos, 0); for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5)) || !strncasecmp (argv[i], "Set", MAX(command_len, 3))) i++; limit_set += _set_rec(&i, argc, argv, name_list, start_qos); } if (exit_code) { list_destroy(name_list); xfree(description); return SLURM_ERROR; } else if (!list_count(name_list)) { list_destroy(name_list); slurmdb_destroy_qos_rec(start_qos); exit_code=1; fprintf(stderr, " Need name of qos to add.\n"); return SLURM_SUCCESS; } if (!g_qos_list) { g_qos_list = acct_storage_g_get_qos(db_conn, my_uid, NULL); if (!g_qos_list) { exit_code=1; fprintf(stderr, " Problem getting qos's " "from database. " "Contact your admin.\n"); list_destroy(name_list); xfree(description); return SLURM_ERROR; } } qos_list = list_create(slurmdb_destroy_qos_rec); itr = list_iterator_create(name_list); while((name = list_next(itr))) { qos = NULL; if (!sacctmgr_find_qos_from_list(g_qos_list, name)) { qos = xmalloc(sizeof(slurmdb_qos_rec_t)); slurmdb_init_qos_rec(qos, 0); qos->name = xstrdup(name); if (start_qos->description) qos->description = xstrdup(start_qos->description); else qos->description = xstrdup(name); qos->flags = start_qos->flags; qos->grace_time = start_qos->grace_time; qos->grp_cpu_mins = start_qos->grp_cpu_mins; qos->grp_cpu_run_mins = start_qos->grp_cpu_run_mins; qos->grp_cpus = start_qos->grp_cpus; qos->grp_jobs = start_qos->grp_jobs; qos->grp_mem = start_qos->grp_mem; qos->grp_nodes = start_qos->grp_nodes; qos->grp_submit_jobs = start_qos->grp_submit_jobs; qos->grp_wall = start_qos->grp_wall; qos->max_cpu_mins_pj = start_qos->max_cpu_mins_pj; qos->max_cpu_run_mins_pu = start_qos->max_cpu_run_mins_pu; qos->max_cpus_pj = start_qos->max_cpus_pj; qos->max_cpus_pu = start_qos->max_cpus_pu; qos->max_jobs_pu = start_qos->max_jobs_pu; qos->max_nodes_pj = start_qos->max_nodes_pj; qos->max_nodes_pu = start_qos->max_nodes_pu; qos->max_submit_jobs_pu = start_qos->max_submit_jobs_pu; qos->max_wall_pj = start_qos->max_wall_pj; qos->preempt_list = copy_char_list(start_qos->preempt_list); qos->preempt_mode = start_qos->preempt_mode; qos->priority = start_qos->priority; qos->usage_factor = start_qos->usage_factor; qos->usage_thres = start_qos->usage_thres; xstrfmtcat(qos_str, " %s\n", name); list_append(qos_list, qos); } } list_iterator_destroy(itr); list_destroy(name_list); if (g_qos_list) { list_destroy(g_qos_list); g_qos_list = NULL; } if (!list_count(qos_list)) { printf(" Nothing new added.\n"); rc = SLURM_ERROR; goto end_it; } if (qos_str) { printf(" Adding QOS(s)\n%s", qos_str); printf(" Settings\n"); if (description) printf(" Description = %s\n", description); else printf(" Description = %s\n", "QOS Name"); sacctmgr_print_qos_limits(start_qos); xfree(qos_str); } notice_thread_init(); if (list_count(qos_list)) rc = acct_storage_g_add_qos(db_conn, my_uid, qos_list); else goto end_it; notice_thread_fini(); if (rc == SLURM_SUCCESS) { if (commit_check("Would you like to commit changes?")) { acct_storage_g_commit(db_conn, 1); } else { printf(" Changes Discarded\n"); acct_storage_g_commit(db_conn, 0); } } else { exit_code=1; fprintf(stderr, " Problem adding QOS: %s\n", slurm_strerror(rc)); rc = SLURM_ERROR; } end_it: list_destroy(qos_list); xfree(description); return rc; }
extern int as_mysql_add_wckeys(mysql_conn_t *mysql_conn, uint32_t uid, List wckey_list) { ListIterator itr = NULL; int rc = SLURM_SUCCESS; slurmdb_wckey_rec_t *object = NULL; char *cols = NULL, *extra = NULL, *vals = NULL, *query = NULL, *tmp_extra = NULL; time_t now = time(NULL); char *user_name = NULL; int affect_rows = 0; int added = 0; List added_user_list = NULL; if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) return ESLURM_ACCESS_DENIED; user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(wckey_list); while ((object = list_next(itr))) { if (!object->cluster || !object->cluster[0] || !object->user || !object->user[0] || !object->name) { error("We need a wckey name (%s), cluster (%s), " "and user (%s) to add.", object->name, object->cluster, object->user); rc = SLURM_ERROR; continue; } if (!added_user_list) added_user_list = list_create(NULL); list_append(added_user_list, object->user); xstrcat(cols, "creation_time, mod_time, user"); xstrfmtcat(vals, "%ld, %ld, '%s'", now, now, object->user); xstrfmtcat(extra, ", mod_time=%ld, user='******'", now, object->user); if (object->name) { xstrcat(cols, ", wckey_name"); xstrfmtcat(vals, ", '%s'", object->name); xstrfmtcat(extra, ", wckey_name='%s'", object->name); } /* When adding, if this isn't a default might as well force it to be 0 to avoid confusion since uninitialized it is NO_VAL. */ if (object->is_def == 1) { xstrcat(cols, ", is_def"); xstrcat(vals, ", 1"); xstrcat(extra, ", is_def=1"); } else { object->is_def = 0; xstrcat(cols, ", is_def"); xstrcat(vals, ", 0"); xstrcat(extra, ", is_def=0"); } xstrfmtcat(query, "insert into \"%s_%s\" (%s) values (%s) " "on duplicate key update deleted=0, " "id_wckey=LAST_INSERT_ID(id_wckey)%s;", object->cluster, wckey_table, cols, vals, extra); if (debug_flags & DEBUG_FLAG_DB_WCKEY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); object->id = mysql_db_insert_ret_id(mysql_conn, query); xfree(query); if (!object->id) { error("Couldn't add wckey %s", object->name); added=0; xfree(cols); xfree(extra); xfree(vals); break; } affect_rows = last_affected_rows(mysql_conn); if (!affect_rows) { debug2("nothing changed %d", affect_rows); xfree(cols); xfree(extra); xfree(vals); continue; } /* we always have a ', ' as the first 2 chars */ tmp_extra = slurm_add_slash_to_quotes(extra+2); xstrfmtcat(query, "insert into %s " "(timestamp, action, name, actor, info, cluster) " "values (%ld, %u, 'id_wckey=%d', '%s', '%s', '%s');", txn_table, now, DBD_ADD_WCKEYS, object->id, user_name, tmp_extra, object->cluster); xfree(tmp_extra); xfree(cols); xfree(extra); xfree(vals); debug4("query\n%s",query); rc = mysql_db_query(mysql_conn, query); xfree(query); if (rc != SLURM_SUCCESS) { error("Couldn't add txn"); } else { if (addto_update_list(mysql_conn->update_list, SLURMDB_ADD_WCKEY, object) == SLURM_SUCCESS) list_remove(itr); added++; } } list_iterator_destroy(itr); xfree(user_name); if (!added) { reset_mysql_conn(mysql_conn); goto end_it; } /* now reset all the other defaults accordingly. (if needed) */ itr = list_iterator_create(wckey_list); while ((object = list_next(itr))) { if ((object->is_def != 1) || !object->cluster || !object->user || !object->name) continue; if ((rc = _reset_default_wckey(mysql_conn, object) != SLURM_SUCCESS)) break; } list_iterator_destroy(itr); end_it: if (rc == SLURM_SUCCESS) _make_sure_users_have_default(mysql_conn, added_user_list); if (added_user_list) list_destroy(added_user_list); return rc; }
extern int sacctmgr_list_qos(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_qos_cond_t *qos_cond = xmalloc(sizeof(slurmdb_qos_cond_t)); int i=0; ListIterator itr = NULL; ListIterator itr2 = NULL; slurmdb_qos_rec_t *qos = NULL; List qos_list = NULL; int field_count = 0; print_field_t *field = NULL; List format_list = list_create(slurm_destroy_char); List print_fields_list; /* types are of print_field_t */ for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp (argv[i], "Where", MAX(command_len, 5)) || !strncasecmp (argv[i], "Set", MAX(command_len, 3))) i++; _set_cond(&i, argc, argv, qos_cond, format_list); } if (exit_code) { slurmdb_destroy_qos_cond(qos_cond); list_destroy(format_list); return SLURM_ERROR; } else if (!list_count(format_list)) { slurm_addto_char_list(format_list, "Name,Prio,GraceT,Preempt,PreemptM," "Flags%40,UsageThres,UsageFactor," "GrpCPUs,GrpCPUMins,GrpCPURunMins," "GrpJ,GrpMEM,GrpN,GrpS,GrpW," "MaxCPUs,MaxCPUMins,MaxN,MaxW," "MaxCPUsPerUser," "MaxJobsPerUser,MaxNodesPerUser," "MaxSubmitJobsPerUser"); } print_fields_list = sacctmgr_process_format_list(format_list); list_destroy(format_list); if (exit_code) { list_destroy(print_fields_list); return SLURM_ERROR; } qos_list = acct_storage_g_get_qos(db_conn, my_uid, qos_cond); slurmdb_destroy_qos_cond(qos_cond); if (!qos_list) { exit_code=1; fprintf(stderr, " Problem with query.\n"); list_destroy(print_fields_list); return SLURM_ERROR; } itr = list_iterator_create(qos_list); itr2 = list_iterator_create(print_fields_list); print_fields_header(print_fields_list); field_count = list_count(print_fields_list); while((qos = list_next(itr))) { int curr_inx = 1; while((field = list_next(itr2))) { switch(field->type) { case PRINT_DESC: field->print_routine( field, qos->description, (curr_inx == field_count)); break; case PRINT_FLAGS: { char *tmp_char = slurmdb_qos_flags_str( qos->flags); field->print_routine( field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; } case PRINT_UT: field->print_routine( field, qos->usage_thres, (curr_inx == field_count)); break; case PRINT_GRACE: field->print_routine( field, (uint64_t)qos->grace_time, (curr_inx == field_count)); break; case PRINT_GRPCM: field->print_routine( field, qos->grp_cpu_mins, (curr_inx == field_count)); break; case PRINT_GRPCRM: field->print_routine( field, qos->grp_cpu_run_mins, (curr_inx == field_count)); break; case PRINT_GRPC: field->print_routine(field, qos->grp_cpus, (curr_inx == field_count)); break; case PRINT_GRPJ: field->print_routine(field, qos->grp_jobs, (curr_inx == field_count)); break; case PRINT_GRPMEM: field->print_routine(field, qos->grp_mem, (curr_inx == field_count)); break; case PRINT_GRPN: field->print_routine(field, qos->grp_nodes, (curr_inx == field_count)); break; case PRINT_GRPS: field->print_routine(field, qos->grp_submit_jobs, (curr_inx == field_count)); break; case PRINT_GRPW: field->print_routine( field, qos->grp_wall, (curr_inx == field_count)); break; case PRINT_ID: field->print_routine( field, qos->id, (curr_inx == field_count)); break; case PRINT_MAXCM: field->print_routine( field, qos->max_cpu_mins_pj, (curr_inx == field_count)); break; case PRINT_MAXCRM: field->print_routine( field, qos->max_cpu_run_mins_pu, (curr_inx == field_count)); break; case PRINT_MAXC: field->print_routine(field, qos->max_cpus_pj, (curr_inx == field_count)); break; case PRINT_MAXCU: field->print_routine(field, qos->max_cpus_pu, (curr_inx == field_count)); break; case PRINT_MAXJ: field->print_routine(field, qos->max_jobs_pu, (curr_inx == field_count)); break; case PRINT_MAXN: field->print_routine(field, qos->max_nodes_pj, (curr_inx == field_count)); break; case PRINT_MAXNU: field->print_routine(field, qos->max_nodes_pu, (curr_inx == field_count)); break; case PRINT_MAXS: field->print_routine(field, qos->max_submit_jobs_pu, (curr_inx == field_count)); break; case PRINT_MAXW: field->print_routine( field, qos->max_wall_pj, (curr_inx == field_count)); break; case PRINT_NAME: field->print_routine( field, qos->name, (curr_inx == field_count)); break; case PRINT_PREE: if (!g_qos_list) g_qos_list = acct_storage_g_get_qos( db_conn, my_uid, NULL); field->print_routine( field, g_qos_list, qos->preempt_bitstr, (curr_inx == field_count)); break; case PRINT_PREEM: { char *tmp_char = "cluster"; if (qos->preempt_mode) tmp_char = xstrtolower( preempt_mode_string( qos->preempt_mode)); field->print_routine( field, tmp_char, (curr_inx == field_count)); break; } case PRINT_PRIO: field->print_routine( field, qos->priority, (curr_inx == field_count)); break; case PRINT_UF: field->print_routine( field, qos->usage_factor, (curr_inx == field_count)); break; default: field->print_routine( field, NULL, (curr_inx == field_count)); break; } curr_inx++; } list_iterator_reset(itr2); printf("\n"); } list_iterator_destroy(itr2); list_iterator_destroy(itr); list_destroy(qos_list); list_destroy(print_fields_list); return rc; }
extern List as_mysql_get_wckeys(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_wckey_cond_t *wckey_cond) { //DEF_TIMERS; char *extra = NULL; char *tmp = NULL; char *cluster_name = NULL; List wckey_list = NULL; int i=0, is_admin=1; uint16_t private_data = 0; slurmdb_user_rec_t user; List use_cluster_list = as_mysql_cluster_list; ListIterator itr; if (!wckey_cond) { xstrcat(extra, " where deleted=0"); goto empty; } if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; private_data = slurm_get_private_data(); if (private_data & PRIVATE_DATA_USERS) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { assoc_mgr_fill_in_user( mysql_conn, &user, 1, NULL); } if (!is_admin && !user.name) { debug("User %u has no assocations, and is not admin, " "so not returning any wckeys.", user.uid); return NULL; } } (void) _setup_wckey_cond_limits(wckey_cond, &extra); if (wckey_cond->cluster_list && list_count(wckey_cond->cluster_list)) use_cluster_list = wckey_cond->cluster_list; empty: xfree(tmp); xstrfmtcat(tmp, "t1.%s", wckey_req_inx[i]); for(i=1; i<WCKEY_REQ_COUNT; i++) { xstrfmtcat(tmp, ", t1.%s", wckey_req_inx[i]); } /* this is here to make sure we are looking at only this user * if this flag is set. We also include any accounts they may be * coordinator of. */ if (!is_admin && (private_data & PRIVATE_DATA_USERS)) xstrfmtcat(extra, " && t1.user='******'", user.name); wckey_list = list_create(slurmdb_destroy_wckey_rec); if (use_cluster_list == as_mysql_cluster_list) slurm_mutex_lock(&as_mysql_cluster_list_lock); //START_TIMER; itr = list_iterator_create(use_cluster_list); while ((cluster_name = list_next(itr))) { if (_cluster_get_wckeys(mysql_conn, wckey_cond, tmp, extra, cluster_name, wckey_list) != SLURM_SUCCESS) { list_destroy(wckey_list); wckey_list = NULL; break; } } list_iterator_destroy(itr); if (use_cluster_list == as_mysql_cluster_list) slurm_mutex_unlock(&as_mysql_cluster_list_lock); xfree(tmp); xfree(extra); //END_TIMER2("get_wckeys"); return wckey_list; }
/* * slurm_job_will_run - determine if a job would execute immediately if * submitted now * IN job_desc_msg - description of resource allocation request * RET 0 on success, otherwise return -1 and set errno to indicate the error */ int slurm_job_will_run (job_desc_msg_t *req) { slurm_msg_t req_msg, resp_msg; will_run_response_msg_t *will_run_resp; char buf[64]; bool host_set = false; int rc; uint32_t cluster_flags = slurmdb_setup_cluster_flags(); char *type = "processors"; /* req.immediate = true; implicit */ if ((req->alloc_node == NULL) && (gethostname_short(buf, sizeof(buf)) == 0)) { req->alloc_node = buf; host_set = true; } slurm_msg_t_init(&req_msg); req_msg.msg_type = REQUEST_JOB_WILL_RUN; req_msg.data = req; rc = slurm_send_recv_controller_msg(&req_msg, &resp_msg); if (host_set) req->alloc_node = NULL; if (rc < 0) return SLURM_SOCKET_ERROR; switch (resp_msg.msg_type) { case RESPONSE_SLURM_RC: if (_handle_rc_msg(&resp_msg) < 0) return SLURM_PROTOCOL_ERROR; break; case RESPONSE_JOB_WILL_RUN: if (cluster_flags & CLUSTER_FLAG_BG) type = "cnodes"; will_run_resp = (will_run_response_msg_t *) resp_msg.data; slurm_make_time_str(&will_run_resp->start_time, buf, sizeof(buf)); info("Job %u to start at %s using %u %s" " on %s", will_run_resp->job_id, buf, will_run_resp->proc_cnt, type, will_run_resp->node_list); if (will_run_resp->preemptee_job_id) { ListIterator itr; uint32_t *job_id_ptr; char *job_list = NULL, *sep = ""; itr = list_iterator_create(will_run_resp-> preemptee_job_id); while ((job_id_ptr = list_next(itr))) { if (job_list) sep = ","; xstrfmtcat(job_list, "%s%u", sep, *job_id_ptr); } info(" Preempts: %s", job_list); xfree(job_list); } slurm_free_will_run_response_msg(will_run_resp); break; default: slurm_seterrno_ret(SLURM_UNEXPECTED_MSG_ERROR); break; } return SLURM_PROTOCOL_SUCCESS; }