list_t* termFreeVars(TERM *t) { list_t *vars, *rvars; lnode_t *node; switch(t->type) { case(TM_VAR): vars = list_create(LISTCOUNT_T_MAX); list_append(vars, lnode_create(t->name)); break; case(TM_ALIAS): vars = list_create(LISTCOUNT_T_MAX); break; case(TM_ABSTR): vars = termFreeVars(t->rterm); while(node = list_find(vars, t->lterm->name, (int(*)(const void*, const void*))strcmp)) lnode_destroy(list_delete(vars, node)); break; case(TM_APPL): vars = termFreeVars(t->lterm); rvars = termFreeVars(t->rterm); list_transfer(vars, rvars, list_first(rvars)); list_destroy(rvars); break; } t->closed = list_isempty(vars); return vars; }
void menu_item_transfer(struct menu_item *item, struct menu *menu) { if (menu == item->owner) return; menu_deselect(item->owner, item); list_transfer(&menu->items, NULL, &item->owner->items, item); item->owner = menu; }
static int _eio_wakeup_handler(eio_handle_t *eio) { char c = 0; int rc = 0; while ((rc = (read(eio->fds[0], &c, 1)) > 0)) { if (c == 1) _mark_shutdown_true(eio->obj_list); } /* move new eio objects from the new_objs to the obj_list */ list_transfer(eio->obj_list, eio->new_objs); if (rc < 0) return error("eio_clear: read: %m"); return 0; }
void list_sort(list_t *list, int compare(const void *, const void *)) { list_t extra; listcount_t middle; lnode_t *node; if (list_count(list) > 1) { middle = list_count(list) / 2; node = list_first_priv(list); list_init(&extra, list_count(list) - middle); while (middle--) node = lnode_next(node); list_transfer(&extra, list, node); list_sort(list, compare); list_sort(&extra, compare); list_merge(list, &extra, compare); } assert (list_is_sorted(list, compare)); }
void list_merge (list_t * dest, list_t * sour, int compare (const void *, const void *)) { lnode_t *dn, *sn, *tn; lnode_t *d_nil = list_nil (dest), *s_nil = list_nil (sour); /* Nothing to do if source and destination list are the same. */ if (dest == sour) return; /* overflow check */ nassert (list_count (sour) + list_count (dest) >= list_count (sour)); /* lists must be sorted */ nassert (list_is_sorted (sour, compare)); nassert (list_is_sorted (dest, compare)); dn = list_first_priv (dest); sn = list_first_priv (sour); while (dn != d_nil && sn != s_nil) { if (compare (lnode_get (dn), lnode_get (sn)) >= 0) { tn = lnode_next (sn); list_delete (sour, sn); list_ins_before (dest, sn, dn); sn = tn; } else { dn = lnode_next (dn); } } if (dn != d_nil) return; if (sn != s_nil) list_transfer (dest, sour, sn); }
extern int as_mysql_add_accts(mysql_conn_t *mysql_conn, uint32_t uid, List acct_list) { ListIterator itr = NULL; int rc = SLURM_SUCCESS; slurmdb_account_rec_t *object = NULL; char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL; time_t now = time(NULL); char *user_name = NULL; char *extra = NULL, *tmp_extra = NULL; int affect_rows = 0; List assoc_list = list_create(slurmdb_destroy_association_rec); if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(acct_list); while ((object = list_next(itr))) { if (!object->name || !object->name[0] || !object->description || !object->description[0] || !object->organization || !object->organization[0]) { error("We need an account name, description, and " "organization to add. %s %s %s", object->name, object->description, object->organization); rc = SLURM_ERROR; continue; } xstrcat(cols, "creation_time, mod_time, name, " "description, organization"); xstrfmtcat(vals, "%ld, %ld, '%s', '%s', '%s'", now, now, object->name, object->description, object->organization); xstrfmtcat(extra, ", description='%s', organization='%s'", object->description, object->organization); query = xstrdup_printf( "insert into %s (%s) values (%s) " "on duplicate key update deleted=0, mod_time=%ld %s;", acct_table, cols, vals, now, extra); if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "query\n%s", query); rc = mysql_db_query(mysql_conn, query); xfree(cols); xfree(vals); xfree(query); if (rc != SLURM_SUCCESS) { error("Couldn't add acct"); xfree(extra); continue; } affect_rows = last_affected_rows(mysql_conn); /* if (debug_flags & DEBUG_FLAG_DB_ASSOC) */ /* DB_DEBUG(mysql_conn->conn, "affected %d", affect_rows); */ if (!affect_rows) { if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "nothing changed"); xfree(extra); continue; } /* we always have a ', ' as the first 2 chars */ tmp_extra = slurm_add_slash_to_quotes(extra+2); if (txn_query) xstrfmtcat(txn_query, ", (%ld, %u, '%s', '%s', '%s')", now, DBD_ADD_ACCOUNTS, object->name, user_name, tmp_extra); else xstrfmtcat(txn_query, "insert into %s " "(timestamp, action, name, actor, info) " "values (%ld, %u, '%s', '%s', '%s')", txn_table, now, DBD_ADD_ACCOUNTS, object->name, user_name, tmp_extra); xfree(tmp_extra); xfree(extra); if (!object->assoc_list) continue; list_transfer(assoc_list, object->assoc_list); } list_iterator_destroy(itr); xfree(user_name); if (rc != SLURM_ERROR) { if (txn_query) { xstrcat(txn_query, ";"); rc = mysql_db_query(mysql_conn, txn_query); xfree(txn_query); if (rc != SLURM_SUCCESS) { error("Couldn't add txn"); rc = SLURM_SUCCESS; } } } else xfree(txn_query); if (list_count(assoc_list)) { if (as_mysql_add_assocs(mysql_conn, uid, assoc_list) == SLURM_ERROR) { error("Problem adding user associations"); rc = SLURM_ERROR; } } list_destroy(assoc_list); return rc; }
/* * as_pg_add_accts - add accounts * * IN pg_conn: database connection * IN uid: user performing the add operation * IN acct_list: accounts to add * RET: error code */ extern int as_pg_add_accts(pgsql_conn_t *pg_conn, uint32_t uid, List acct_list) { ListIterator itr = NULL; slurmdb_account_rec_t *object = NULL; List assoc_list = NULL; int rc = SLURM_SUCCESS; char *user_name = NULL, *query = NULL, *txn_query = NULL; char *rec = NULL, *info = NULL; time_t now = time(NULL); if (check_db_connection(pg_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; assoc_list = list_create(slurmdb_destroy_association_rec); user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(acct_list); while((object = list_next(itr))) { if(!object->name || !object->description || !object->organization) { error("as/pg: add_accts: We need an account name, " "description, and organization to add. %s %s %s", object->name, object->description, object->organization); rc = SLURM_ERROR; continue; } /* order of vals must match structure of acct_table */ rec = xstrdup_printf("(%ld, %ld, 0, '%s', '%s', '%s')", now, now, object->name, object->description, object->organization); query = xstrdup_printf("SELECT public.add_acct(%s);", rec); xfree(rec); rc = DEF_QUERY_RET_RC; if(rc != SLURM_SUCCESS) { error("as/pg: couldn't add acct %s", object->name); continue; } info = xstrdup_printf("description='%s', organization='%s'", object->description, object->organization); if(txn_query) xstrfmtcat(txn_query, ", (%ld, %u, '%s', '%s', $$%s$$)", now, DBD_ADD_ACCOUNTS, object->name, user_name, info); else xstrfmtcat(txn_query, "INSERT INTO %s " "(timestamp, action, name, actor, info) " "VALUES (%ld, %u, '%s', '%s', $$%s$$)", txn_table, now, DBD_ADD_ACCOUNTS, object->name, user_name, info); xfree(info); if(!object->assoc_list) continue; list_transfer(assoc_list, object->assoc_list); } list_iterator_destroy(itr); xfree(user_name); if(rc == SLURM_SUCCESS) { if(txn_query) { xstrcat(txn_query, ";"); rc = pgsql_db_query(pg_conn->db_conn, txn_query); xfree(txn_query); if(rc != SLURM_SUCCESS) { error("as/pg: add_accts: couldn't add txn"); rc = SLURM_SUCCESS; } } } else xfree(txn_query); if(rc == SLURM_SUCCESS && list_count(assoc_list)) { if(acct_storage_p_add_associations(pg_conn, uid, assoc_list) != SLURM_SUCCESS) { error("as/pg: add_accts: problem adding account " "associations"); rc = SLURM_ERROR; } } list_destroy(assoc_list); return rc; }
static int _cluster_get_jobs(mysql_conn_t *mysql_conn, slurmdb_user_rec_t *user, slurmdb_job_cond_t *job_cond, char *cluster_name, char *job_fields, char *step_fields, char *sent_extra, bool is_admin, int only_pending, List sent_list) { char *query = NULL; char *extra = xstrdup(sent_extra); uint16_t private_data = slurm_get_private_data(); slurmdb_selected_step_t *selected_step = NULL; MYSQL_RES *result = NULL, *step_result = NULL; MYSQL_ROW row, step_row; slurmdb_job_rec_t *job = NULL; slurmdb_step_rec_t *step = NULL; time_t now = time(NULL); List job_list = list_create(slurmdb_destroy_job_rec); ListIterator itr = NULL, itr2 = NULL; List local_cluster_list = NULL; int set = 0; char *prefix="t2"; int rc = SLURM_SUCCESS; int last_id = -1, curr_id = -1; local_cluster_t *curr_cluster = NULL; /* 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_JOBS)) { query = xstrdup_printf("select lft from \"%s_%s\" " "where user='******'", cluster_name, assoc_table, user->name); if (user->coord_accts) { slurmdb_coord_rec_t *coord = NULL; itr = list_iterator_create(user->coord_accts); while ((coord = list_next(itr))) { xstrfmtcat(query, " || acct='%s'", coord->name); } list_iterator_destroy(itr); } if (debug_flags & DEBUG_FLAG_DB_JOB) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(extra); xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); set = 0; while ((row = mysql_fetch_row(result))) { if (set) { xstrfmtcat(extra, " || (%s between %s.lft and %s.rgt)", row[0], prefix, prefix); } else { set = 1; if (extra) xstrfmtcat(extra, " && ((%s between %s.lft " "and %s.rgt)", row[0], prefix, prefix); else xstrfmtcat(extra, " where ((%s between %s.lft " "and %s.rgt)", row[0], prefix, prefix); } } mysql_free_result(result); if (set) xstrcat(extra, ")"); else { xfree(extra); debug("User %s has no assocations, and is not admin, " "so not returning any jobs.", user->name); /* This user has no valid associations, so * they will not have any jobs. */ goto end_it; } } setup_job_cluster_cond_limits(mysql_conn, job_cond, cluster_name, &extra); query = xstrdup_printf("select %s from \"%s_%s\" as t1 " "left join \"%s_%s\" as t2 " "on t1.id_assoc=t2.id_assoc " "left join \"%s_%s\" as t3 " "on t1.id_resv=t3.id_resv && " "((t1.time_start && " "(t3.time_start < t1.time_start && " "(t3.time_end >= t1.time_start || " "t3.time_end = 0))) || " "((t3.time_start < t1.time_submit && " "(t3.time_end >= t1.time_submit || " "t3.time_end = 0)) || " "(t3.time_start > t1.time_submit)))", job_fields, cluster_name, job_table, cluster_name, assoc_table, cluster_name, resv_table); if (extra) { xstrcat(query, extra); xfree(extra); } /* Here we want to order them this way in such a way so it is easy to look for duplicates, it is also easy to sort the resized jobs. */ xstrcat(query, " group by id_job, time_submit desc"); if (debug_flags & DEBUG_FLAG_DB_JOB) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); /* Here we set up environment to check used nodes of jobs. Since we store the bitmap of the entire cluster we can use that to set up a hostlist and set up the bitmap to make things work. This should go before the setup of conds since we could update the start/end time. */ if (job_cond && job_cond->used_nodes) { local_cluster_list = setup_cluster_list_with_inx( mysql_conn, job_cond, (void **)&curr_cluster); if (!local_cluster_list) { rc = SLURM_ERROR; goto end_it; } } while ((row = mysql_fetch_row(result))) { char *id = row[JOB_REQ_ID]; bool job_ended = 0; int start = slurm_atoul(row[JOB_REQ_START]); curr_id = slurm_atoul(row[JOB_REQ_JOBID]); if (job_cond && !job_cond->duplicates && (curr_id == last_id) && (slurm_atoul(row[JOB_REQ_STATE]) != JOB_RESIZING)) continue; /* check the bitmap to see if this is one of the jobs we are looking for */ /* Use start time instead of submit time because node * indexes are determined at start time and not submit. */ if (!good_nodes_from_inx(local_cluster_list, (void **)&curr_cluster, row[JOB_REQ_NODE_INX], start)) { last_id = curr_id; continue; } job = slurmdb_create_job_rec(); job->state = slurm_atoul(row[JOB_REQ_STATE]); if (curr_id == last_id) /* put in reverse so we order by the submit getting larger which it is given to us in reverse order from the database */ list_prepend(job_list, job); else list_append(job_list, job); last_id = curr_id; if (row[JOB_REQ_GRES_ALLOC]) job->alloc_gres = xstrdup(row[JOB_REQ_GRES_ALLOC]); else job->alloc_gres = xstrdup(""); job->alloc_nodes = slurm_atoul(row[JOB_REQ_ALLOC_NODES]); job->associd = slurm_atoul(row[JOB_REQ_ASSOCID]); job->array_job_id = slurm_atoul(row[JOB_REQ_ARRAYJOBID]); job->array_task_id = slurm_atoul(row[JOB_REQ_ARRAYTASKID]); job->resvid = slurm_atoul(row[JOB_REQ_RESVID]); /* This shouldn't happen with new jobs, but older jobs * could of been added without a start and so the * array_task_id would be 0 instead of it's real value */ if (!job->array_job_id && !job->array_task_id) job->array_task_id = NO_VAL; if (row[JOB_REQ_RESV_NAME] && row[JOB_REQ_RESV_NAME][0]) job->resv_name = xstrdup(row[JOB_REQ_RESV_NAME]); job->cluster = xstrdup(cluster_name); /* we want a blank wckey if the name is null */ if (row[JOB_REQ_WCKEY]) job->wckey = xstrdup(row[JOB_REQ_WCKEY]); else job->wckey = xstrdup(""); job->wckeyid = slurm_atoul(row[JOB_REQ_WCKEYID]); if (row[JOB_REQ_USER_NAME]) job->user = xstrdup(row[JOB_REQ_USER_NAME]); else job->uid = slurm_atoul(row[JOB_REQ_UID]); if (row[JOB_REQ_LFT]) job->lft = slurm_atoul(row[JOB_REQ_LFT]); if (row[JOB_REQ_ACCOUNT] && row[JOB_REQ_ACCOUNT][0]) job->account = xstrdup(row[JOB_REQ_ACCOUNT]); else if (row[JOB_REQ_ACCOUNT1] && row[JOB_REQ_ACCOUNT1][0]) job->account = xstrdup(row[JOB_REQ_ACCOUNT1]); if (row[JOB_REQ_ARRAY_STR] && row[JOB_REQ_ARRAY_STR][0]) job->array_task_str = xstrdup(row[JOB_REQ_ARRAY_STR]); if (row[JOB_REQ_ARRAY_MAX]) job->array_max_tasks = slurm_atoul(row[JOB_REQ_ARRAY_MAX]); if (row[JOB_REQ_BLOCKID]) job->blockid = xstrdup(row[JOB_REQ_BLOCKID]); job->eligible = slurm_atoul(row[JOB_REQ_ELIGIBLE]); job->submit = slurm_atoul(row[JOB_REQ_SUBMIT]); job->start = start; job->end = slurm_atoul(row[JOB_REQ_END]); job->timelimit = slurm_atoul(row[JOB_REQ_TIMELIMIT]); /* since the job->end could be set later end it here */ if (job->end) { job_ended = 1; if (!job->start || (job->start > job->end)) job->start = job->end; } if (job_cond && !job_cond->without_usage_truncation && job_cond->usage_start) { if (job->start && (job->start < job_cond->usage_start)) job->start = job_cond->usage_start; if (!job->end || job->end > job_cond->usage_end) job->end = job_cond->usage_end; if (!job->start) job->start = job->end; job->elapsed = job->end - job->start; if (row[JOB_REQ_SUSPENDED]) { MYSQL_RES *result2 = NULL; MYSQL_ROW row2; /* get the suspended time for this job */ query = xstrdup_printf( "select time_start, time_end from " "\"%s_%s\" where " "(time_start < %ld && (time_end >= %ld " "|| time_end = 0)) && job_db_inx=%s " "order by time_start", cluster_name, suspend_table, job_cond->usage_end, job_cond->usage_start, id); debug4("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result2 = mysql_db_query_ret( mysql_conn, query, 0))) { FREE_NULL_LIST(job_list); job_list = NULL; break; } xfree(query); while ((row2 = mysql_fetch_row(result2))) { time_t local_start = slurm_atoul(row2[0]); time_t local_end = slurm_atoul(row2[1]); if (!local_start) continue; if (job->start > local_start) local_start = job->start; if (job->end < local_end) local_end = job->end; if ((local_end - local_start) < 1) continue; job->elapsed -= (local_end - local_start); job->suspended += (local_end - local_start); } mysql_free_result(result2); } } else { job->suspended = slurm_atoul(row[JOB_REQ_SUSPENDED]); /* fix the suspended number to be correct */ if (job->state == JOB_SUSPENDED) job->suspended = now - job->suspended; if (!job->start) { job->elapsed = 0; } else if (!job->end) { job->elapsed = now - job->start; } else { job->elapsed = job->end - job->start; } job->elapsed -= job->suspended; } if ((int)job->elapsed < 0) job->elapsed = 0; job->jobid = curr_id; job->jobname = xstrdup(row[JOB_REQ_NAME]); job->gid = slurm_atoul(row[JOB_REQ_GID]); job->exitcode = slurm_atoul(row[JOB_REQ_EXIT_CODE]); job->derived_ec = slurm_atoul(row[JOB_REQ_DERIVED_EC]); job->derived_es = xstrdup(row[JOB_REQ_DERIVED_ES]); if (row[JOB_REQ_PARTITION]) job->partition = xstrdup(row[JOB_REQ_PARTITION]); if (row[JOB_REQ_NODELIST]) job->nodes = xstrdup(row[JOB_REQ_NODELIST]); if (!job->nodes || !xstrcmp(job->nodes, "(null)")) { xfree(job->nodes); job->nodes = xstrdup("(unknown)"); } job->track_steps = slurm_atoul(row[JOB_REQ_TRACKSTEPS]); job->priority = slurm_atoul(row[JOB_REQ_PRIORITY]); job->req_cpus = slurm_atoul(row[JOB_REQ_REQ_CPUS]); if (row[JOB_REQ_GRES_REQ]) job->req_gres = xstrdup(row[JOB_REQ_GRES_REQ]); else job->req_gres = xstrdup(""); job->req_mem = slurm_atoul(row[JOB_REQ_REQ_MEM]); job->requid = slurm_atoul(row[JOB_REQ_KILL_REQUID]); job->qosid = slurm_atoul(row[JOB_REQ_QOS]); job->show_full = 1; if (row[JOB_REQ_TRESA]) job->tres_alloc_str = xstrdup(row[JOB_REQ_TRESA]); if (row[JOB_REQ_TRESR]) job->tres_req_str = xstrdup(row[JOB_REQ_TRESR]); if (only_pending || (job_cond && job_cond->without_steps)) goto skip_steps; if (job_cond && job_cond->step_list && list_count(job_cond->step_list)) { set = 0; itr = list_iterator_create(job_cond->step_list); while ((selected_step = list_next(itr))) { if ((selected_step->jobid != job->jobid) && (selected_step->jobid != job->array_job_id)) { continue; } else if ((selected_step->array_task_id != INFINITE) && (selected_step->array_task_id != job->array_task_id)) continue; else if (selected_step->stepid == NO_VAL) { job->show_full = 1; break; } else if (selected_step->stepid == INFINITE) selected_step->stepid = SLURM_BATCH_SCRIPT; if (set) xstrcat(extra, " || "); else xstrcat(extra, " && ("); /* The stepid could be -2 so use %d not %u */ xstrfmtcat(extra, "t1.id_step=%d", selected_step->stepid); set = 1; job->show_full = 0; /* Set it back just in case we are looking at a job array. */ if (selected_step->stepid == SLURM_BATCH_SCRIPT) selected_step->stepid = INFINITE; } list_iterator_destroy(itr); if (set) xstrcat(extra, ")"); } query = xstrdup_printf("select %s from \"%s_%s\" as t1 " "where t1.job_db_inx=%s", step_fields, cluster_name, step_table, id); if (extra) { xstrcat(query, extra); xfree(extra); } if (debug_flags & DEBUG_FLAG_DB_STEP) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(step_result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); /* Querying the steps in the fashion was faster than doing only 1 query and then matching the steps up later with the job. */ while ((step_row = mysql_fetch_row(step_result))) { /* check the bitmap to see if this is one of the steps we are looking for */ if (!good_nodes_from_inx(local_cluster_list, (void **)&curr_cluster, step_row[STEP_REQ_NODE_INX], start)) continue; step = slurmdb_create_step_rec(); step->tot_cpu_sec = 0; step->tot_cpu_usec = 0; step->job_ptr = job; if (!job->first_step_ptr) job->first_step_ptr = step; list_append(job->steps, step); step->stepid = slurm_atoul(step_row[STEP_REQ_STEPID]); /* info("got step %u.%u", */ /* job->header.jobnum, step->stepnum); */ step->state = slurm_atoul(step_row[STEP_REQ_STATE]); step->exitcode = slurm_atoul(step_row[STEP_REQ_EXIT_CODE]); step->nnodes = slurm_atoul(step_row[STEP_REQ_NODES]); step->ntasks = slurm_atoul(step_row[STEP_REQ_TASKS]); step->task_dist = slurm_atoul(step_row[STEP_REQ_TASKDIST]); step->start = slurm_atoul(step_row[STEP_REQ_START]); step->end = slurm_atoul(step_row[STEP_REQ_END]); /* if the job has ended end the step also */ if (!step->end && job_ended) { step->end = job->end; step->state = job->state; } if (job_cond && !job_cond->without_usage_truncation && job_cond->usage_start) { if (step->start && (step->start < job_cond->usage_start)) step->start = job_cond->usage_start; if (!step->start && step->end) step->start = step->end; if (!step->end || (step->end > job_cond->usage_end)) step->end = job_cond->usage_end; } /* figure this out by start stop */ step->suspended = slurm_atoul(step_row[STEP_REQ_SUSPENDED]); if (!step->start) { step->elapsed = 0; } else if (!step->end) { step->elapsed = now - step->start; } else { step->elapsed = step->end - step->start; } step->elapsed -= step->suspended; if ((int)step->elapsed < 0) step->elapsed = 0; step->req_cpufreq_min = slurm_atoul( step_row[STEP_REQ_REQ_CPUFREQ_MIN]); step->req_cpufreq_max = slurm_atoul( step_row[STEP_REQ_REQ_CPUFREQ_MAX]); step->req_cpufreq_gov = slurm_atoul( step_row[STEP_REQ_REQ_CPUFREQ_GOV]); step->stepname = xstrdup(step_row[STEP_REQ_NAME]); step->nodes = xstrdup(step_row[STEP_REQ_NODELIST]); step->requid = slurm_atoul(step_row[STEP_REQ_KILL_REQUID]); step->stats.cpu_min = slurm_atoul( step_row[STEP_REQ_MIN_CPU]); if (step->stats.cpu_min != NO_VAL) { step->user_cpu_sec = slurm_atoul( step_row[STEP_REQ_USER_SEC]); step->user_cpu_usec = slurm_atoul( step_row[STEP_REQ_USER_USEC]); step->sys_cpu_sec = slurm_atoul(step_row[STEP_REQ_SYS_SEC]); step->sys_cpu_usec = slurm_atoul( step_row[STEP_REQ_SYS_USEC]); step->tot_cpu_sec += step->user_cpu_sec + step->sys_cpu_sec; step->tot_cpu_usec += step->user_cpu_usec + step->sys_cpu_usec; step->stats.disk_read_max = atof(step_row[STEP_REQ_MAX_DISK_READ]); step->stats.disk_read_max_taskid = slurm_atoul( step_row[STEP_REQ_MAX_DISK_READ_TASK]); step->stats.disk_read_ave = atof(step_row[STEP_REQ_AVE_DISK_READ]); step->stats.disk_write_max = atof(step_row[STEP_REQ_MAX_DISK_WRITE]); step->stats.disk_write_max_taskid = slurm_atoul( step_row[STEP_REQ_MAX_DISK_WRITE_TASK]); step->stats.disk_write_ave = atof(step_row[STEP_REQ_AVE_DISK_WRITE]); step->stats.vsize_max = slurm_atoul( step_row[STEP_REQ_MAX_VSIZE]); step->stats.vsize_max_taskid = slurm_atoul( step_row[STEP_REQ_MAX_VSIZE_TASK]); step->stats.vsize_ave = atof(step_row[STEP_REQ_AVE_VSIZE]); step->stats.rss_max = slurm_atoul(step_row[STEP_REQ_MAX_RSS]); step->stats.rss_max_taskid = slurm_atoul( step_row[STEP_REQ_MAX_RSS_TASK]); step->stats.rss_ave = atof(step_row[STEP_REQ_AVE_RSS]); step->stats.pages_max = slurm_atoul( step_row[STEP_REQ_MAX_PAGES]); step->stats.pages_max_taskid = slurm_atoul( step_row[STEP_REQ_MAX_PAGES_TASK]); step->stats.pages_ave = atof(step_row[STEP_REQ_AVE_PAGES]); step->stats.cpu_min_taskid = slurm_atoul( step_row[STEP_REQ_MIN_CPU_TASK]); step->stats.cpu_ave = atof(step_row[STEP_REQ_AVE_CPU]); step->stats.act_cpufreq = atof(step_row[STEP_REQ_ACT_CPUFREQ]); step->stats.consumed_energy = atof( step_row[STEP_REQ_CONSUMED_ENERGY]); step->stats.vsize_max_nodeid = slurm_atoul( step_row[STEP_REQ_MAX_VSIZE_NODE]); step->stats.rss_max_nodeid = slurm_atoul( step_row[STEP_REQ_MAX_RSS_NODE]); step->stats.pages_max_nodeid = slurm_atoul( step_row[STEP_REQ_MAX_PAGES_NODE]); step->stats.cpu_min_nodeid = slurm_atoul( step_row[STEP_REQ_MIN_CPU_NODE]); } if (step_row[STEP_REQ_TRES]) step->tres_alloc_str = xstrdup(step_row[STEP_REQ_TRES]); } mysql_free_result(step_result); if (!job->track_steps) { uint64_t j_cpus, s_cpus; /* If we don't have track_steps we want to see if we have multiple steps. If we only have 1 step check the job name against the step name in most all cases it will be different. If it is different print out the step separate. It could also be a single step/allocation where the job was allocated more than the step requested (eg. CR_Socket). */ if (list_count(job->steps) > 1) job->track_steps = 1; else if (step && (xstrcmp(step->stepname, job->jobname) || (((j_cpus = slurmdb_find_tres_count_in_string( job->tres_alloc_str, TRES_CPU)) != INFINITE64) && ((s_cpus = slurmdb_find_tres_count_in_string( step->tres_alloc_str, TRES_CPU)) != INFINITE64) && j_cpus != s_cpus))) job->track_steps = 1; } skip_steps: /* need to reset here to make the above test valid */ step = NULL; } mysql_free_result(result); end_it: if (itr2) list_iterator_destroy(itr2); FREE_NULL_LIST(local_cluster_list); if (rc == SLURM_SUCCESS) list_transfer(sent_list, job_list); FREE_NULL_LIST(job_list); return rc; }
extern int as_mysql_add_users(mysql_conn_t *mysql_conn, uint32_t uid, List user_list) { ListIterator itr = NULL; int rc = SLURM_SUCCESS; slurmdb_user_rec_t *object = NULL; char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL; time_t now = time(NULL); char *user_name = NULL; char *extra = NULL, *tmp_extra = NULL; int affect_rows = 0; List assoc_list = list_create(slurmdb_destroy_association_rec); List wckey_list = list_create(slurmdb_destroy_wckey_rec); if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(user_list); while ((object = list_next(itr))) { if (!object->name || !object->name[0]) { error("We need a user name and " "default acct to add."); rc = SLURM_ERROR; continue; } xstrcat(cols, "creation_time, mod_time, name"); xstrfmtcat(vals, "%ld, %ld, '%s'", (long)now, (long)now, object->name); if (object->admin_level != SLURMDB_ADMIN_NOTSET) { xstrcat(cols, ", admin_level"); xstrfmtcat(vals, ", %u", object->admin_level); xstrfmtcat(extra, ", admin_level=%u", object->admin_level); } else xstrfmtcat(extra, ", admin_level=%u", SLURMDB_ADMIN_NONE); query = xstrdup_printf( "insert into %s (%s) values (%s) " "on duplicate key update deleted=0, mod_time=%ld %s;", user_table, cols, vals, (long)now, extra); xfree(cols); xfree(vals); rc = mysql_db_query(mysql_conn, query); xfree(query); if (rc != SLURM_SUCCESS) { error("Couldn't add user %s", object->name); xfree(extra); continue; } affect_rows = last_affected_rows(mysql_conn); if (!affect_rows) { debug("nothing changed"); xfree(extra); continue; } if (addto_update_list(mysql_conn->update_list, SLURMDB_ADD_USER, object) == SLURM_SUCCESS) list_remove(itr); /* we always have a ', ' as the first 2 chars */ tmp_extra = slurm_add_slash_to_quotes(extra+2); if (txn_query) xstrfmtcat(txn_query, ", (%ld, %u, '%s', '%s', '%s')", (long)now, DBD_ADD_USERS, object->name, user_name, tmp_extra); else xstrfmtcat(txn_query, "insert into %s " "(timestamp, action, name, actor, info) " "values (%ld, %u, '%s', '%s', '%s')", txn_table, (long)now, DBD_ADD_USERS, object->name, user_name, tmp_extra); xfree(tmp_extra); xfree(extra); /* For < 2.2 systems we need to set the is_def flag in the default association/wckey so as to make sure we get it set correctly. */ if (object->assoc_list) { slurmdb_association_rec_t *assoc = NULL; ListIterator assoc_itr = list_iterator_create(object->assoc_list); while ((assoc = list_next(assoc_itr))) { /* We need to mark all of the associations with this account since there could be multiple clusters here. */ if (!strcmp(assoc->acct, object->default_acct)) assoc->is_def = 1; } list_iterator_destroy(assoc_itr); list_transfer(assoc_list, object->assoc_list); } if (object->wckey_list) { if (object->default_wckey) { slurmdb_wckey_rec_t *wckey = NULL; ListIterator wckey_itr = list_iterator_create( object->wckey_list); while ((wckey = list_next(wckey_itr))) { /* We need to mark all of the wckeys with this account since there could be multiple clusters here. */ if (!strcmp(wckey->name, object->default_wckey)) wckey->is_def = 1; } list_iterator_destroy(wckey_itr); } list_transfer(wckey_list, object->wckey_list); } } list_iterator_destroy(itr); xfree(user_name); if (rc != SLURM_ERROR) { if (txn_query) { xstrcat(txn_query, ";"); rc = mysql_db_query(mysql_conn, txn_query); xfree(txn_query); if (rc != SLURM_SUCCESS) { error("Couldn't add txn"); rc = SLURM_SUCCESS; } } } else xfree(txn_query); if (list_count(assoc_list)) { if (as_mysql_add_assocs(mysql_conn, uid, assoc_list) == SLURM_ERROR) { error("Problem adding user associations"); rc = SLURM_ERROR; } } list_destroy(assoc_list); if (list_count(wckey_list)) { if (as_mysql_add_wckeys(mysql_conn, uid, wckey_list) == SLURM_ERROR) { error("Problem adding user wckeys"); rc = SLURM_ERROR; } } list_destroy(wckey_list); return rc; }
extern List as_mysql_get_users(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_user_cond_t *user_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; List user_list = NULL; ListIterator itr = NULL; char *object = NULL; int set = 0; int i=0, is_admin=1; MYSQL_RES *result = NULL; MYSQL_ROW row; uint16_t private_data = 0; slurmdb_user_rec_t user; /* if this changes you will need to edit the corresponding enum */ char *user_req_inx[] = { "name", "admin_level" }; enum { USER_REQ_NAME, USER_REQ_AL, USER_REQ_COUNT }; 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 users.", user.uid); return NULL; } } if (!user_cond) { xstrcat(extra, "where deleted=0"); set = 1; goto empty; } if (user_cond->with_deleted) xstrcat(extra, "where (deleted=0 || deleted=1)"); else xstrcat(extra, "where deleted=0"); user_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond); if (user_list) { if (!user_cond->assoc_cond) user_cond->assoc_cond = xmalloc(sizeof(slurmdb_association_rec_t)); if (!user_cond->assoc_cond->user_list) user_cond->assoc_cond->user_list = user_list; else { list_transfer(user_cond->assoc_cond->user_list, user_list); list_destroy(user_list); } user_list = NULL; } else if ((user_cond->def_acct_list && list_count(user_cond->def_acct_list)) || (user_cond->def_wckey_list && list_count(user_cond->def_wckey_list))) return NULL; if (user_cond->assoc_cond && user_cond->assoc_cond->user_list && list_count(user_cond->assoc_cond->user_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(user_cond->assoc_cond->user_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (user_cond->admin_level != SLURMDB_ADMIN_NOTSET) { xstrfmtcat(extra, " && admin_level=%u", user_cond->admin_level); set = 1; } empty: /* This is here to make sure we are looking at only this user * if this flag is set. */ if (!is_admin && (private_data & PRIVATE_DATA_USERS)) { xstrfmtcat(extra, " && name='%s'", user.name); } xfree(tmp); xstrfmtcat(tmp, "%s", user_req_inx[0]); for(i=1; i<USER_REQ_COUNT; i++) { xstrfmtcat(tmp, ", %s", user_req_inx[i]); } query = xstrdup_printf("select %s from %s %s", tmp, user_table, extra); xfree(tmp); xfree(extra); debug3("%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); return NULL; } xfree(query); user_list = list_create(slurmdb_destroy_user_rec); while ((row = mysql_fetch_row(result))) { slurmdb_user_rec_t *user = xmalloc(sizeof(slurmdb_user_rec_t)); list_append(user_list, user); user->name = xstrdup(row[USER_REQ_NAME]); user->admin_level = slurm_atoul(row[USER_REQ_AL]); if (user_cond && user_cond->with_coords) _get_user_coords(mysql_conn, user); } mysql_free_result(result); if (user_cond && (user_cond->with_assocs || (user_cond->assoc_cond && user_cond->assoc_cond->only_defs))) { ListIterator assoc_itr = NULL; slurmdb_user_rec_t *user = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = NULL; /* Make sure we don't get any non-user associations * this is done by at least having a user_list * defined */ if (!user_cond->assoc_cond) user_cond->assoc_cond = xmalloc(sizeof(slurmdb_association_cond_t)); if (!user_cond->assoc_cond->user_list) user_cond->assoc_cond->user_list = list_create(NULL); user_cond->assoc_cond->with_deleted = user_cond->with_deleted; assoc_list = as_mysql_get_assocs( mysql_conn, uid, user_cond->assoc_cond); if (!assoc_list) { error("no associations"); goto get_wckeys; } itr = list_iterator_create(user_list); assoc_itr = list_iterator_create(assoc_list); while ((user = list_next(itr))) { while ((assoc = list_next(assoc_itr))) { if (strcmp(assoc->user, user->name)) continue; /* Set up the default. This is needed * for older versions primarily that * don't have the notion of default * account per cluster. */ if (!user->default_acct && (assoc->is_def == 1)) user->default_acct = xstrdup(assoc->acct); if (!user_cond->with_assocs) { /* We just got the default so no reason to hang around if we aren't getting the associations. */ if (user->default_acct) break; else continue; } if (!user->assoc_list) user->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(user->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } get_wckeys: if (user_cond && (user_cond->with_wckeys || (user_cond->assoc_cond && user_cond->assoc_cond->only_defs))) { ListIterator wckey_itr = NULL; slurmdb_user_rec_t *user = NULL; slurmdb_wckey_rec_t *wckey = NULL; List wckey_list = NULL; slurmdb_wckey_cond_t wckey_cond; memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t)); if (user_cond->assoc_cond) { wckey_cond.user_list = user_cond->assoc_cond->user_list; wckey_cond.cluster_list = user_cond->assoc_cond->cluster_list; wckey_cond.only_defs = user_cond->assoc_cond->only_defs; } wckey_list = as_mysql_get_wckeys(mysql_conn, uid, &wckey_cond); if (!wckey_list) return user_list; itr = list_iterator_create(user_list); wckey_itr = list_iterator_create(wckey_list); while ((user = list_next(itr))) { while ((wckey = list_next(wckey_itr))) { if (strcmp(wckey->user, user->name)) continue; /* Set up the default. This is needed * for older versions primarily that * don't have the notion of default * wckey per cluster. */ if (!user->default_wckey && (wckey->is_def == 1)) user->default_wckey = xstrdup(wckey->name); /* We just got the default so no reason to hang around if we aren't getting the wckeys. */ if (!user_cond->with_wckeys) { /* We just got the default so no reason to hang around if we aren't getting the wckeys. */ if (user->default_wckey) break; else continue; } if (!user->wckey_list) user->wckey_list = list_create( slurmdb_destroy_wckey_rec); list_append(user->wckey_list, wckey); list_remove(wckey_itr); } list_iterator_reset(wckey_itr); /* If a user doesn't have a default wckey (they might not of had track_wckeys on), set it now. */ if (!user->default_wckey) user->default_wckey = xstrdup(""); } list_iterator_destroy(itr); list_iterator_destroy(wckey_itr); list_destroy(wckey_list); } return user_list; }
void *_fwd_tree_thread(void *arg) { fwd_tree_t *fwd_tree = (fwd_tree_t *)arg; List ret_list = NULL; char *name = NULL; char *buf = NULL; slurm_msg_t send_msg; slurm_msg_t_init(&send_msg); send_msg.msg_type = fwd_tree->orig_msg->msg_type; send_msg.data = fwd_tree->orig_msg->data; /* repeat until we are sure the message was sent */ while ((name = hostlist_shift(fwd_tree->tree_hl))) { if (slurm_conf_get_addr(name, &send_msg.address) == SLURM_ERROR) { error("fwd_tree_thread: can't find address for host " "%s, check slurm.conf", name); slurm_mutex_lock(fwd_tree->tree_mutex); mark_as_failed_forward(&fwd_tree->ret_list, name, SLURM_UNKNOWN_FORWARD_ADDR); pthread_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); free(name); continue; } send_msg.forward.timeout = fwd_tree->timeout; if((send_msg.forward.cnt = hostlist_count(fwd_tree->tree_hl))) { buf = hostlist_ranged_string_xmalloc( fwd_tree->tree_hl); send_msg.forward.nodelist = buf; } else send_msg.forward.nodelist = NULL; if (send_msg.forward.nodelist && send_msg.forward.nodelist[0]) { debug3("Tree sending to %s along with %s", name, send_msg.forward.nodelist); } else debug3("Tree sending to %s", name); ret_list = slurm_send_addr_recv_msgs(&send_msg, name, fwd_tree->timeout); xfree(send_msg.forward.nodelist); if(ret_list) { slurm_mutex_lock(fwd_tree->tree_mutex); list_transfer(fwd_tree->ret_list, ret_list); pthread_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); list_destroy(ret_list); } else { /* This should never happen (when this was written slurm_send_addr_recv_msgs always returned a list */ error("fwd_tree_thread: no return list given from " "slurm_send_addr_recv_msgs spawned for %s", name); slurm_mutex_lock(fwd_tree->tree_mutex); mark_as_failed_forward( &fwd_tree->ret_list, name, SLURM_COMMUNICATIONS_CONNECTION_ERROR); pthread_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); free(name); continue; } free(name); /* check for error and try again */ if(errno == SLURM_COMMUNICATIONS_CONNECTION_ERROR) continue; break; } _destroy_tree_fwd(fwd_tree); return NULL; }
static int _cluster_get_wckeys(mysql_conn_t *mysql_conn, slurmdb_wckey_cond_t *wckey_cond, char *fields, char *extra, char *cluster_name, List sent_list) { List wckey_list = NULL; MYSQL_RES *result = NULL; MYSQL_ROW row; char *query = NULL; bool with_usage = 0; if (wckey_cond) with_usage = wckey_cond->with_usage; xstrfmtcat(query, "select distinct %s from \"%s_%s\" as t1%s " "order by wckey_name, user;", fields, cluster_name, wckey_table, extra); if (debug_flags & DEBUG_FLAG_DB_WCKEY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); if (mysql_errno(mysql_conn->db_conn) == ER_NO_SUCH_TABLE) return SLURM_SUCCESS; else return SLURM_ERROR; } xfree(query); if (!mysql_num_rows(result)) { mysql_free_result(result); return SLURM_SUCCESS; } wckey_list = list_create(slurmdb_destroy_wckey_rec); while ((row = mysql_fetch_row(result))) { slurmdb_wckey_rec_t *wckey = xmalloc(sizeof(slurmdb_wckey_rec_t)); list_append(wckey_list, wckey); wckey->id = slurm_atoul(row[WCKEY_REQ_ID]); wckey->is_def = slurm_atoul(row[WCKEY_REQ_DEFAULT]); wckey->user = xstrdup(row[WCKEY_REQ_USER]); /* we want a blank wckey if the name is null */ if (row[WCKEY_REQ_NAME]) wckey->name = xstrdup(row[WCKEY_REQ_NAME]); else wckey->name = xstrdup(""); wckey->cluster = xstrdup(cluster_name); } mysql_free_result(result); if (with_usage && wckey_list && list_count(wckey_list)) get_usage_for_list(mysql_conn, DBD_GET_WCKEY_USAGE, wckey_list, cluster_name, wckey_cond->usage_start, wckey_cond->usage_end); list_transfer(sent_list, wckey_list); list_destroy(wckey_list); return SLURM_SUCCESS; }
/* block_state_mutex should be unlocked before calling this */ extern int free_block_list(uint32_t job_id, List track_list, bool destroy, bool wait) { bg_record_t *bg_record = NULL; int retries; ListIterator itr = NULL; bg_free_block_list_t *bg_free_list; pthread_attr_t attr_agent; pthread_t thread_agent; if (!track_list || !list_count(track_list)) return SLURM_SUCCESS; bg_free_list = xmalloc(sizeof(bg_free_block_list_t)); bg_free_list->track_list = list_create(NULL); bg_free_list->destroy = destroy; bg_free_list->job_id = job_id; slurm_mutex_lock(&block_state_mutex); list_transfer(bg_free_list->track_list, track_list); itr = list_iterator_create(bg_free_list->track_list); while ((bg_record = list_next(itr))) { if (bg_record->magic != BLOCK_MAGIC) { error("block was already destroyed %p", bg_record); continue; } bg_record->free_cnt++; if (bg_record->job_ptr && !IS_JOB_FINISHED(bg_record->job_ptr)) { info("We are freeing a block (%s) that has job %u(%u).", bg_record->bg_block_id, bg_record->job_ptr->job_id, bg_record->job_running); /* This is not thread safe if called from bg_job_place.c anywhere from within submit_job() or at startup. */ slurm_mutex_unlock(&block_state_mutex); bg_requeue_job(bg_record->job_ptr->job_id, 0); slurm_mutex_lock(&block_state_mutex); } if (remove_from_bg_list(bg_lists->job_running, bg_record) == SLURM_SUCCESS) num_unused_cpus += bg_record->cpu_cnt; } list_iterator_destroy(itr); slurm_mutex_unlock(&block_state_mutex); if (wait) { /* Track_freeing_blocks waits until the list is done and frees the memory of bg_free_list. */ _track_freeing_blocks(bg_free_list); return SLURM_SUCCESS; } /* _track_freeing_blocks handles cleanup */ slurm_attr_init(&attr_agent); if (pthread_attr_setdetachstate(&attr_agent, PTHREAD_CREATE_DETACHED)) error("pthread_attr_setdetachstate error %m"); retries = 0; while (pthread_create(&thread_agent, &attr_agent, _track_freeing_blocks, bg_free_list)) { error("pthread_create error %m"); if (++retries > MAX_PTHREAD_RETRIES) fatal("Can't create " "pthread"); /* sleep and retry */ usleep(1000); } slurm_attr_destroy(&attr_agent); return SLURM_SUCCESS; }
static List _create_block_list(partition_info_msg_t *part_info_ptr, block_info_msg_t *block_info_ptr) { int i; static List block_list = NULL; static partition_info_msg_t *last_part_info_ptr = NULL; static block_info_msg_t *last_block_info_ptr = NULL; List last_list = NULL; ListIterator last_list_itr = NULL; sview_block_info_t *block_ptr = NULL; char tmp_mp_str[50]; if (block_list && (part_info_ptr == last_part_info_ptr) && (block_info_ptr == last_block_info_ptr)) return block_list; last_part_info_ptr = part_info_ptr; if (block_list) { /* Only the partition info changed so lets update just that part. */ if (block_info_ptr == last_block_info_ptr) { ListIterator itr = list_iterator_create(block_list); while ((block_ptr = list_next(itr))) _set_block_partition(part_info_ptr, block_ptr); return block_list; } last_list = block_list; } block_list = list_create(_block_list_del); if (!block_list) { g_print("malloc error\n"); return NULL; } last_block_info_ptr = block_info_ptr; if (last_list) last_list_itr = list_iterator_create(last_list); for (i=0; i<block_info_ptr->record_count; i++) { /* If we don't have a block name just continue since ths block hasn't been made in the system yet. */ if (!block_info_ptr->block_array[i].bg_block_id) continue; block_ptr = NULL; if (last_list_itr) { while ((block_ptr = list_next(last_list_itr))) { if (!xstrcmp(block_ptr->bg_block_name, block_info_ptr-> block_array[i].bg_block_id)) { list_remove(last_list_itr); _block_info_free(block_ptr); break; } } list_iterator_reset(last_list_itr); } if (!block_ptr) block_ptr = xmalloc(sizeof(sview_block_info_t)); block_ptr->pos = i; block_ptr->bg_block_name = xstrdup(block_info_ptr-> block_array[i].bg_block_id); block_ptr->color_inx = atoi(block_ptr->bg_block_name+7); /* on some systems they make there own blocks named whatever they want, so doing this fixes what could be a negative number. */ if (block_ptr->color_inx < 0) block_ptr->color_inx = i; block_ptr->color_inx %= sview_colors_cnt; block_ptr->mp_str = xstrdup(block_info_ptr->block_array[i].mp_str); if (block_info_ptr->block_array[i].ionode_str) { block_ptr->small_block = 1; snprintf(tmp_mp_str, sizeof(tmp_mp_str), "%s[%s]", block_ptr->mp_str, block_info_ptr->block_array[i].ionode_str); xfree(block_ptr->mp_str); block_ptr->mp_str = xstrdup(tmp_mp_str); } block_ptr->reason = xstrdup(block_info_ptr->block_array[i].reason); if (cluster_flags & CLUSTER_FLAG_BGP) { block_ptr->imagelinux = xstrdup( block_info_ptr->block_array[i].linuximage); block_ptr->imageramdisk = xstrdup( block_info_ptr->block_array[i].ramdiskimage); } else if (cluster_flags & CLUSTER_FLAG_BGL) { block_ptr->imageblrts = xstrdup( block_info_ptr->block_array[i].blrtsimage); block_ptr->imagelinux = xstrdup( block_info_ptr->block_array[i].linuximage); block_ptr->imageramdisk = xstrdup( block_info_ptr->block_array[i].ramdiskimage); } block_ptr->imagemloader = xstrdup( block_info_ptr->block_array[i].mloaderimage); block_ptr->state = block_info_ptr->block_array[i].state; memcpy(block_ptr->bg_conn_type, block_info_ptr->block_array[i].conn_type, sizeof(block_ptr->bg_conn_type)); if (cluster_flags & CLUSTER_FLAG_BGL) block_ptr->bg_node_use = block_info_ptr->block_array[i].node_use; block_ptr->cnode_cnt = block_info_ptr->block_array[i].cnode_cnt; block_ptr->cnode_err_cnt = block_info_ptr->block_array[i].cnode_err_cnt; block_ptr->mp_inx = block_info_ptr->block_array[i].mp_inx; _set_block_partition(part_info_ptr, block_ptr); block_ptr->job_list = list_create(slurm_free_block_job_info); if (block_info_ptr->block_array[i].job_list) list_transfer(block_ptr->job_list, block_info_ptr->block_array[i].job_list); if (block_ptr->bg_conn_type[0] >= SELECT_SMALL) block_ptr->size = 0; list_append(block_list, block_ptr); } list_sort(block_list, (ListCmpF)_sview_block_sort_aval_dec); if (last_list) { list_iterator_destroy(last_list_itr); FREE_NULL_LIST(last_list); } return block_list; }
void *_fwd_tree_thread(void *arg) { fwd_tree_t *fwd_tree = (fwd_tree_t *)arg; List ret_list = NULL; char *name = NULL; char *buf = NULL; slurm_msg_t send_msg; slurm_msg_t_init(&send_msg); send_msg.msg_type = fwd_tree->orig_msg->msg_type; send_msg.data = fwd_tree->orig_msg->data; send_msg.protocol_version = fwd_tree->orig_msg->protocol_version; /* repeat until we are sure the message was sent */ while ((name = hostlist_shift(fwd_tree->tree_hl))) { if (slurm_conf_get_addr(name, &send_msg.address) == SLURM_ERROR) { error("fwd_tree_thread: can't find address for host " "%s, check slurm.conf", name); slurm_mutex_lock(fwd_tree->tree_mutex); mark_as_failed_forward(&fwd_tree->ret_list, name, SLURM_UNKNOWN_FORWARD_ADDR); slurm_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); free(name); continue; } send_msg.forward.timeout = fwd_tree->timeout; if ((send_msg.forward.cnt = hostlist_count(fwd_tree->tree_hl))){ buf = hostlist_ranged_string_xmalloc( fwd_tree->tree_hl); send_msg.forward.nodelist = buf; } else send_msg.forward.nodelist = NULL; if (send_msg.forward.nodelist && send_msg.forward.nodelist[0]) { debug3("Tree sending to %s along with %s", name, send_msg.forward.nodelist); } else debug3("Tree sending to %s", name); ret_list = slurm_send_addr_recv_msgs(&send_msg, name, fwd_tree->timeout); xfree(send_msg.forward.nodelist); if (ret_list) { int ret_cnt = list_count(ret_list); /* This is most common if a slurmd is running an older version of Slurm than the originator of the message. */ if ((ret_cnt <= send_msg.forward.cnt) && (errno != SLURM_COMMUNICATIONS_CONNECTION_ERROR)) { error("fwd_tree_thread: %s failed to forward " "the message, expecting %d ret got only " "%d", name, send_msg.forward.cnt + 1, ret_cnt); if (ret_cnt > 1) { /* not likely */ ret_data_info_t *ret_data_info = NULL; ListIterator itr = list_iterator_create(ret_list); while ((ret_data_info = list_next(itr))) { if (xstrcmp(ret_data_info-> node_name, name)) hostlist_delete_host( fwd_tree-> tree_hl, ret_data_info-> node_name); } list_iterator_destroy(itr); } } slurm_mutex_lock(fwd_tree->tree_mutex); list_transfer(fwd_tree->ret_list, ret_list); slurm_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); FREE_NULL_LIST(ret_list); /* try next node */ if (ret_cnt <= send_msg.forward.cnt) { free(name); /* Abandon tree. This way if all the * nodes in the branch are down we * don't have to time out for each * node serially. */ _start_msg_tree_internal( fwd_tree->tree_hl, NULL, fwd_tree, hostlist_count(fwd_tree->tree_hl)); continue; } } else { /* This should never happen (when this was * written slurm_send_addr_recv_msgs always * returned a list */ error("fwd_tree_thread: no return list given from " "slurm_send_addr_recv_msgs spawned for %s", name); slurm_mutex_lock(fwd_tree->tree_mutex); mark_as_failed_forward( &fwd_tree->ret_list, name, SLURM_COMMUNICATIONS_CONNECTION_ERROR); slurm_cond_signal(fwd_tree->notify); slurm_mutex_unlock(fwd_tree->tree_mutex); free(name); continue; } free(name); /* check for error and try again */ if (errno == SLURM_COMMUNICATIONS_CONNECTION_ERROR) continue; break; } _destroy_tree_fwd(fwd_tree); return NULL; }
/* block_state_mutex should be unlocked before calling this */ extern void free_block_list(uint32_t job_id, List track_list, bool destroy, bool wait) { bg_record_t *bg_record = NULL; int retries; ListIterator itr = NULL; bg_free_block_list_t *bg_free_list; pthread_attr_t attr_agent; pthread_t thread_agent; List kill_job_list = NULL; kill_job_struct_t *freeit; if (!track_list || !list_count(track_list)) return; bg_free_list = xmalloc(sizeof(bg_free_block_list_t)); bg_free_list->track_list = list_create(NULL); bg_free_list->destroy = destroy; bg_free_list->job_id = job_id; slurm_mutex_lock(&block_state_mutex); list_transfer(bg_free_list->track_list, track_list); itr = list_iterator_create(bg_free_list->track_list); while ((bg_record = list_next(itr))) { if (bg_record->magic != BLOCK_MAGIC) { error("block was already destroyed %p", bg_record); continue; } bg_record->free_cnt++; /* just so we don't over write a different thread that wants this block destroyed */ if (destroy && !bg_record->destroy) bg_record->destroy = destroy; if (destroy && (bg_record->state & BG_BLOCK_ERROR_FLAG)) resume_block(bg_record); /* This means we are wanting this block free so we can run this job on it, so it is ok to have the job remain here. Only checking for jobs should go below this. */ if (bg_record->modifying) { debug("free_block_list: Just FYI, we are " "freeing a block (%s) that " "has at least one pending job.", bg_record->bg_block_id); continue; } if (bg_record->job_ptr && !IS_JOB_FINISHED(bg_record->job_ptr)) { info("We are freeing a block (%s) that " "has job %u(%u).", bg_record->bg_block_id, bg_record->job_ptr->job_id, bg_record->job_running); if (!kill_job_list) kill_job_list = bg_status_create_kill_job_list(); freeit = xmalloc(sizeof(kill_job_struct_t)); freeit->jobid = bg_record->job_ptr->job_id; list_push(kill_job_list, freeit); } else if (bg_record->job_list && list_count(bg_record->job_list)) { struct job_record *job_ptr; ListIterator itr; if (!kill_job_list) kill_job_list = bg_status_create_kill_job_list(); info("We are freeing a block (%s) that has at " "least 1 job.", bg_record->bg_block_id); itr = list_iterator_create(bg_record->job_list); while ((job_ptr = list_next(itr))) { if ((job_ptr->magic != JOB_MAGIC) || IS_JOB_FINISHED(job_ptr)) continue; freeit = xmalloc(sizeof(kill_job_struct_t)); freeit->jobid = job_ptr->job_id; list_push(kill_job_list, freeit); } list_iterator_destroy(itr); } } list_iterator_destroy(itr); slurm_mutex_unlock(&block_state_mutex); if (kill_job_list) { bg_status_process_kill_job_list(kill_job_list, JOB_FAILED, 0); FREE_NULL_LIST(kill_job_list); } if (wait) { /* Track_freeing_blocks waits until the list is done and frees the memory of bg_free_list. */ _track_freeing_blocks(bg_free_list); return; } /* _track_freeing_blocks handles cleanup */ slurm_attr_init(&attr_agent); if (pthread_attr_setdetachstate(&attr_agent, PTHREAD_CREATE_DETACHED)) error("pthread_attr_setdetachstate error %m"); retries = 0; while (pthread_create(&thread_agent, &attr_agent, _track_freeing_blocks, bg_free_list)) { error("pthread_create error %m"); if (++retries > MAX_PTHREAD_RETRIES) fatal("Can't create pthread"); /* sleep and retry */ usleep(1000); } slurm_attr_destroy(&attr_agent); return; }
extern int as_mysql_add_accts(mysql_conn_t *mysql_conn, uint32_t uid, List acct_list) { ListIterator itr = NULL; int rc = SLURM_SUCCESS; slurmdb_account_rec_t *object = NULL; char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL; time_t now = time(NULL); char *user_name = NULL; char *extra = NULL, *tmp_extra = NULL; int affect_rows = 0; List assoc_list = list_create(slurmdb_destroy_assoc_rec); if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) { slurmdb_user_rec_t user; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; if (!is_user_any_coord(mysql_conn, &user)) { error("Only admins/operators/coordinators " "can add accounts"); return ESLURM_ACCESS_DENIED; } /* If the user is a coord of any acct they can add * accounts they are only able to make associations to * these accounts if they are coordinators of the * parent they are trying to add to */ } user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(acct_list); while ((object = list_next(itr))) { if (!object->name || !object->name[0] || !object->description || !object->description[0] || !object->organization || !object->organization[0]) { error("We need an account name, description, and " "organization to add. %s %s %s", object->name, object->description, object->organization); rc = SLURM_ERROR; continue; } xstrcat(cols, "creation_time, mod_time, name, " "description, organization"); xstrfmtcat(vals, "%ld, %ld, '%s', '%s', '%s'", now, now, object->name, object->description, object->organization); xstrfmtcat(extra, ", description='%s', organization='%s'", object->description, object->organization); query = xstrdup_printf( "insert into %s (%s) values (%s) " "on duplicate key update deleted=0, mod_time=%ld %s;", acct_table, cols, vals, now, extra); if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "query\n%s", query); rc = mysql_db_query(mysql_conn, query); xfree(cols); xfree(vals); xfree(query); if (rc != SLURM_SUCCESS) { error("Couldn't add acct"); xfree(extra); continue; } affect_rows = last_affected_rows(mysql_conn); /* if (debug_flags & DEBUG_FLAG_DB_ASSOC) */ /* DB_DEBUG(mysql_conn->conn, "affected %d", affect_rows); */ if (!affect_rows) { if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "nothing changed"); xfree(extra); continue; } /* we always have a ', ' as the first 2 chars */ tmp_extra = slurm_add_slash_to_quotes(extra+2); if (txn_query) xstrfmtcat(txn_query, ", (%ld, %u, '%s', '%s', '%s')", now, DBD_ADD_ACCOUNTS, object->name, user_name, tmp_extra); else xstrfmtcat(txn_query, "insert into %s " "(timestamp, action, name, actor, info) " "values (%ld, %u, '%s', '%s', '%s')", txn_table, now, DBD_ADD_ACCOUNTS, object->name, user_name, tmp_extra); xfree(tmp_extra); xfree(extra); if (!object->assoc_list) continue; if (!assoc_list) assoc_list = list_create(slurmdb_destroy_assoc_rec); list_transfer(assoc_list, object->assoc_list); } list_iterator_destroy(itr); xfree(user_name); if (rc != SLURM_ERROR) { if (txn_query) { xstrcat(txn_query, ";"); rc = mysql_db_query(mysql_conn, txn_query); xfree(txn_query); if (rc != SLURM_SUCCESS) { error("Couldn't add txn"); rc = SLURM_SUCCESS; } } } else xfree(txn_query); if (assoc_list && list_count(assoc_list)) { if ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list)) != SLURM_SUCCESS) error("Problem adding accounts associations"); } FREE_NULL_LIST(assoc_list); return rc; }