extern int as_mysql_fix_runaway_jobs(mysql_conn_t *mysql_conn, uint32_t uid, List runaway_jobs) { char *query = NULL, *job_ids = NULL; slurmdb_job_rec_t *job = NULL; ListIterator iter = NULL; int rc = SLURM_SUCCESS; slurmdb_job_rec_t *first_job; list_sort(runaway_jobs, _job_sort_by_start_time); first_job = list_peek(runaway_jobs); 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 fix runaway jobs"); return ESLURM_ACCESS_DENIED; } } iter = list_iterator_create(runaway_jobs); while ((job = list_next(iter))) { xstrfmtcat(job_ids, "%s%d", ((job_ids) ? "," : ""), job->jobid); } query = xstrdup_printf("UPDATE \"%s_%s\" SET time_end=" "GREATEST(time_start, time_eligible, time_submit), " "state=%d WHERE id_job IN (%s);", mysql_conn->cluster_name, job_table, JOB_COMPLETE, job_ids); if (debug_flags & DEBUG_FLAG_DB_QUERY) DB_DEBUG(mysql_conn->conn, "query\n%s", query); mysql_db_query(mysql_conn, query); xfree(query); xfree(job_ids); /* Set rollup to the the last day of the previous month of the first * runaway job */ rc = _first_job_roll_up(mysql_conn, first_job->start); if (rc != SLURM_SUCCESS) { error("Failed to fix runaway jobs"); return SLURM_ERROR; } return rc; }
extern List as_mysql_get_accts(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_account_cond_t *acct_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; List acct_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 *acct_req_inx[] = { "name", "description", "organization" }; enum { SLURMDB_REQ_NAME, SLURMDB_REQ_DESC, SLURMDB_REQ_ORG, SLURMDB_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_ACCOUNTS) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { if (!is_user_any_coord(mysql_conn, &user)) { error("Only admins/coordinators " "can look at account usage"); errno = ESLURM_ACCESS_DENIED; return NULL; } } } if (!acct_cond) { xstrcat(extra, "where deleted=0"); goto empty; } if (acct_cond->with_deleted) xstrcat(extra, "where (deleted=0 || deleted=1)"); else xstrcat(extra, "where deleted=0"); if (acct_cond->assoc_cond && acct_cond->assoc_cond->acct_list && list_count(acct_cond->assoc_cond->acct_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->assoc_cond->acct_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (acct_cond->description_list && list_count(acct_cond->description_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->description_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "description='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (acct_cond->organization_list && list_count(acct_cond->organization_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(acct_cond->organization_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "organization='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } empty: xfree(tmp); xstrfmtcat(tmp, "%s", acct_req_inx[i]); for(i=1; i<SLURMDB_REQ_COUNT; i++) { xstrfmtcat(tmp, ", %s", acct_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_ACCOUNTS)) { slurmdb_coord_rec_t *coord = NULL; set = 0; itr = list_iterator_create(user.coord_accts); while ((coord = list_next(itr))) { if (set) { xstrfmtcat(extra, " || name='%s'", coord->name); } else { set = 1; xstrfmtcat(extra, " && (name='%s'", coord->name); } } list_iterator_destroy(itr); if (set) xstrcat(extra,")"); } query = xstrdup_printf("select %s from %s %s", tmp, acct_table, extra); xfree(tmp); xfree(extra); if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "query\n%s", query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); return NULL; } xfree(query); acct_list = list_create(slurmdb_destroy_account_rec); if (acct_cond && acct_cond->assoc_cond && acct_cond->with_assocs) { /* We are going to be freeing the inners of this list in the acct->name so we don't free it here */ if (acct_cond->assoc_cond->acct_list) list_destroy(acct_cond->assoc_cond->acct_list); acct_cond->assoc_cond->acct_list = list_create(NULL); acct_cond->assoc_cond->with_deleted = acct_cond->with_deleted; } while ((row = mysql_fetch_row(result))) { slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); list_append(acct_list, acct); acct->name = xstrdup(row[SLURMDB_REQ_NAME]); acct->description = xstrdup(row[SLURMDB_REQ_DESC]); acct->organization = xstrdup(row[SLURMDB_REQ_ORG]); if (acct_cond && acct_cond->with_coords) { _get_account_coords(mysql_conn, acct); } if (acct_cond && acct_cond->with_assocs) { if (!acct_cond->assoc_cond) { acct_cond->assoc_cond = xmalloc( sizeof(slurmdb_association_cond_t)); } list_append(acct_cond->assoc_cond->acct_list, acct->name); } } mysql_free_result(result); if (acct_cond && acct_cond->with_assocs && acct_cond->assoc_cond && list_count(acct_cond->assoc_cond->acct_list)) { ListIterator assoc_itr = NULL; slurmdb_account_rec_t *acct = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = as_mysql_get_assocs( mysql_conn, uid, acct_cond->assoc_cond); if (!assoc_list) { error("no associations"); return acct_list; } itr = list_iterator_create(acct_list); assoc_itr = list_iterator_create(assoc_list); while ((acct = list_next(itr))) { while ((assoc = list_next(assoc_itr))) { if (strcmp(assoc->acct, acct->name)) continue; if (!acct->assoc_list) acct->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(acct->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); if (!acct->assoc_list) list_remove(itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } return acct_list; }
/* * as_pg_get_accts - get accounts * * IN pg_conn: database connection * IN uid: user performing the get operation * IN acct_cond: accounts to get * RET: list of accounts */ extern List as_pg_get_accts(pgsql_conn_t *pg_conn, uid_t uid, slurmdb_account_cond_t *acct_cond) { DEF_VARS; char *cond = NULL; List acct_list = NULL; ListIterator itr = NULL; int set=0, is_admin=1; slurmdb_user_rec_t user; /* no need to free lists */ char *ga_fields = "name, description, organization"; enum { F_NAME, F_DESC, F_ORG, F_COUNT }; if (check_db_connection(pg_conn) != SLURM_SUCCESS) return NULL; if (check_user_op(pg_conn, uid, PRIVATE_DATA_ACCOUNTS, &is_admin, &user) != SLURM_SUCCESS) { error("as/pg: user(%u) not found in db", uid); errno = ESLURM_USER_ID_MISSING; return NULL; } if (!is_admin && ! is_user_any_coord(pg_conn, &user)) { errno = ESLURM_ACCESS_DENIED; return NULL; } if(!acct_cond) { xstrcat(cond, "WHERE deleted=0"); goto empty; } if(acct_cond->with_deleted) xstrcat(cond, "WHERE (deleted=0 OR deleted=1)"); else xstrcat(cond, "WHERE deleted=0"); if(acct_cond->assoc_cond) concat_cond_list(acct_cond->assoc_cond->acct_list, NULL, "name", &cond); concat_cond_list(acct_cond->description_list, NULL, "description", &cond); concat_cond_list(acct_cond->organization_list, NULL, "organization", &cond); empty: if(!is_admin) { slurmdb_coord_rec_t *coord = NULL; set = 0; itr = list_iterator_create(user.coord_accts); while((coord = list_next(itr))) { if(set) { xstrfmtcat(cond, " OR name='%s'", coord->name); } else { set = 1; xstrfmtcat(cond, " AND (name='%s'", coord->name); } } list_iterator_destroy(itr); if(set) xstrcat(cond,")"); } query = xstrdup_printf("SELECT %s FROM %s %s", ga_fields, acct_table, cond); xfree(cond); result = DEF_QUERY_RET; if (!result) return NULL; acct_list = list_create(slurmdb_destroy_account_rec); if(acct_cond && acct_cond->with_assocs) { if(!acct_cond->assoc_cond) acct_cond->assoc_cond = xmalloc( sizeof(slurmdb_association_cond_t)); else if(acct_cond->assoc_cond->acct_list) list_destroy(acct_cond->assoc_cond->acct_list); acct_cond->assoc_cond->acct_list = list_create(NULL); } FOR_EACH_ROW { slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t)); list_append(acct_list, acct); acct->name = xstrdup(ROW(F_NAME)); acct->description = xstrdup(ROW(F_DESC)); acct->organization = xstrdup(ROW(F_ORG)); if(acct_cond && acct_cond->with_coords) _get_account_coords(pg_conn, acct); if(acct_cond && acct_cond->with_assocs) { list_append(acct_cond->assoc_cond->acct_list, acct->name); } } END_EACH_ROW; PQclear(result); /* get associations */ if(acct_cond && acct_cond->with_assocs && list_count(acct_cond->assoc_cond->acct_list)) { ListIterator assoc_itr = NULL; slurmdb_account_rec_t *acct = NULL; slurmdb_association_rec_t *assoc = NULL; List assoc_list = acct_storage_p_get_associations( pg_conn, uid, acct_cond->assoc_cond); if(!assoc_list) { error("as/pg: get_accounts: no associations"); return acct_list; } itr = list_iterator_create(acct_list); assoc_itr = list_iterator_create(assoc_list); while((acct = list_next(itr))) { while((assoc = list_next(assoc_itr))) { if(strcmp(assoc->acct, acct->name)) continue; if(!acct->assoc_list) acct->assoc_list = list_create( slurmdb_destroy_association_rec); list_append(acct->assoc_list, assoc); list_remove(assoc_itr); } list_iterator_reset(assoc_itr); if(!acct->assoc_list) /* problem acct */ list_remove(itr); } list_iterator_destroy(itr); list_iterator_destroy(assoc_itr); list_destroy(assoc_list); } return acct_list; }
extern List as_mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, uid_t uid, slurmdb_job_cond_t *job_cond) { char *extra = NULL; char *tmp = NULL, *tmp2 = NULL; ListIterator itr = NULL; int is_admin=1; int i; List job_list = NULL; uint16_t private_data = 0; slurmdb_user_rec_t user; int only_pending = 0; List use_cluster_list = as_mysql_cluster_list; char *cluster_name; assoc_mgr_lock_t locks = { NO_LOCK, NO_LOCK, NO_LOCK, NO_LOCK, READ_LOCK, NO_LOCK, NO_LOCK }; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; private_data = slurm_get_private_data(); if (private_data & PRIVATE_DATA_JOBS) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { /* Only fill in the coordinator accounts here we will check them later when we actually try to get the jobs. */ is_user_any_coord(mysql_conn, &user); } if (!is_admin && !user.name) { debug("User %u has no assocations, and is not admin, " "so not returning any jobs.", user.uid); return NULL; } } if (job_cond && job_cond->state_list && (list_count(job_cond->state_list) == 1) && (slurm_atoul(list_peek(job_cond->state_list)) == JOB_PENDING)) only_pending = 1; setup_job_cond_limits(job_cond, &extra); xfree(tmp); xstrfmtcat(tmp, "%s", job_req_inx[0]); for(i=1; i<JOB_REQ_COUNT; i++) { xstrfmtcat(tmp, ", %s", job_req_inx[i]); } xfree(tmp2); xstrfmtcat(tmp2, "%s", step_req_inx[0]); for(i=1; i<STEP_REQ_COUNT; i++) { xstrfmtcat(tmp2, ", %s", step_req_inx[i]); } if (job_cond && job_cond->cluster_list && list_count(job_cond->cluster_list)) use_cluster_list = job_cond->cluster_list; else slurm_mutex_lock(&as_mysql_cluster_list_lock); assoc_mgr_lock(&locks); job_list = list_create(slurmdb_destroy_job_rec); itr = list_iterator_create(use_cluster_list); while ((cluster_name = list_next(itr))) { int rc; if ((rc = _cluster_get_jobs(mysql_conn, &user, job_cond, cluster_name, tmp, tmp2, extra, is_admin, only_pending, job_list)) != SLURM_SUCCESS) error("Problem getting jobs for cluster %s", cluster_name); } list_iterator_destroy(itr); assoc_mgr_unlock(&locks); if (use_cluster_list == as_mysql_cluster_list) slurm_mutex_unlock(&as_mysql_cluster_list_lock); xfree(tmp); xfree(tmp2); xfree(extra); return job_list; }
extern List as_mysql_remove_coord(mysql_conn_t *mysql_conn, uint32_t uid, List acct_list, slurmdb_user_cond_t *user_cond) { char *query = NULL, *object = NULL, *extra = NULL, *last_user = NULL; char *user_name = NULL; time_t now = time(NULL); int set = 0, is_admin=0, rc = SLURM_SUCCESS; ListIterator itr = NULL; slurmdb_user_rec_t *user_rec = NULL; List ret_list = NULL; List user_list = NULL; MYSQL_RES *result = NULL; MYSQL_ROW row; slurmdb_user_rec_t user; if (!user_cond && !acct_list) { error("we need something to remove"); return NULL; } else if (user_cond && user_cond->assoc_cond) user_list = user_cond->assoc_cond->user_list; if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { if (!is_user_any_coord(mysql_conn, &user)) { error("Only admins/coordinators can " "remove coordinators"); errno = ESLURM_ACCESS_DENIED; return NULL; } } /* Leave it this way since we are using extra below */ if (user_list && list_count(user_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, "("); itr = list_iterator_create(user_list); while ((object = list_next(itr))) { if (!object[0]) continue; if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "user='******'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (acct_list && list_count(acct_list)) { set = 0; if (extra) xstrcat(extra, " && ("); else xstrcat(extra, "("); itr = list_iterator_create(acct_list); while ((object = list_next(itr))) { if (!object[0]) continue; if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "acct='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (!extra) { errno = SLURM_ERROR; debug3("No conditions given"); return NULL; } query = xstrdup_printf( "select user, acct from %s where deleted=0 && %s order by user", acct_coord_table, 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); xfree(extra); errno = SLURM_ERROR; return NULL; } xfree(query); ret_list = list_create(slurm_destroy_char); user_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) { if (!is_admin) { slurmdb_coord_rec_t *coord = NULL; if (!user.coord_accts) { // This should never // happen error("We are here with no coord accts"); errno = ESLURM_ACCESS_DENIED; list_destroy(ret_list); list_destroy(user_list); xfree(extra); mysql_free_result(result); return NULL; } itr = list_iterator_create(user.coord_accts); while ((coord = list_next(itr))) { if (!strcasecmp(coord->name, row[1])) break; } list_iterator_destroy(itr); if (!coord) { error("User %s(%d) does not have the " "ability to change this account (%s)", user.name, user.uid, row[1]); errno = ESLURM_ACCESS_DENIED; list_destroy(ret_list); list_destroy(user_list); xfree(extra); mysql_free_result(result); return NULL; } } if (!last_user || strcasecmp(last_user, row[0])) { list_append(user_list, xstrdup(row[0])); last_user = row[0]; } list_append(ret_list, xstrdup_printf("U = %-9s A = %-10s", row[0], row[1])); } mysql_free_result(result); user_name = uid_to_string((uid_t) uid); rc = remove_common(mysql_conn, DBD_REMOVE_ACCOUNT_COORDS, now, user_name, acct_coord_table, extra, NULL, NULL, NULL, NULL); xfree(user_name); xfree(extra); if (rc == SLURM_ERROR) { list_destroy(ret_list); list_destroy(user_list); errno = SLURM_ERROR; return NULL; } /* get the update list set */ itr = list_iterator_create(user_list); while ((last_user = list_next(itr))) { user_rec = xmalloc(sizeof(slurmdb_user_rec_t)); user_rec->name = xstrdup(last_user); _get_user_coords(mysql_conn, user_rec); if (addto_update_list(mysql_conn->update_list, SLURMDB_REMOVE_COORD, user_rec) != SLURM_SUCCESS) slurmdb_destroy_user_rec(user_rec); } list_iterator_destroy(itr); list_destroy(user_list); return ret_list; }
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; }
extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid, void *in, slurmdbd_msg_type_t type, time_t start, time_t end) { int rc = SLURM_SUCCESS; int i=0, is_admin=1; MYSQL_RES *result = NULL; MYSQL_ROW row; char *tmp = NULL; char *my_usage_table = NULL; slurmdb_association_rec_t *slurmdb_assoc = in; slurmdb_wckey_rec_t *slurmdb_wckey = in; char *query = NULL; char *username = NULL; uint16_t private_data = 0; slurmdb_user_rec_t user; List *my_list; uint32_t id = NO_VAL; char *cluster_name = NULL; char **usage_req_inx = NULL; enum { USAGE_ID, USAGE_START, USAGE_ACPU, USAGE_COUNT, USAGE_ENERGY }; switch (type) { case DBD_GET_ASSOC_USAGE: { char *temp_usage[] = { "t3.id_assoc", "t1.time_start", "t1.alloc_cpu_secs" }; usage_req_inx = temp_usage; id = slurmdb_assoc->id; cluster_name = slurmdb_assoc->cluster; username = slurmdb_assoc->user; my_list = &slurmdb_assoc->accounting_list; my_usage_table = assoc_day_table; break; } case DBD_GET_WCKEY_USAGE: { char *temp_usage[] = { "id_wckey", "time_start", "alloc_cpu_secs" }; usage_req_inx = temp_usage; id = slurmdb_wckey->id; cluster_name = slurmdb_wckey->cluster; username = slurmdb_wckey->user; my_list = &slurmdb_wckey->accounting_list; my_usage_table = wckey_day_table; break; } case DBD_GET_CLUSTER_USAGE: { return _get_cluster_usage(mysql_conn, uid, in, type, start, end); break; } default: error("Unknown usage type %d", type); return SLURM_ERROR; break; } if (!id) { error("We need an id to set data for getting usage"); return SLURM_ERROR; } else if (!cluster_name) { error("We need a cluster_name to set data for getting usage"); return SLURM_ERROR; } if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; private_data = slurm_get_private_data(); if (private_data & PRIVATE_DATA_USAGE) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { ListIterator itr = NULL; slurmdb_coord_rec_t *coord = NULL; if (username && !strcmp(slurmdb_assoc->user, user.name)) goto is_user; if (type != DBD_GET_ASSOC_USAGE) goto bad_user; if (!slurmdb_assoc->acct) { debug("No account name given " "in association."); goto bad_user; } if (!is_user_any_coord(mysql_conn, &user)) { debug4("This user is not a coordinator."); goto bad_user; } /* Existance of user.coord_accts is checked in is_user_any_coord. */ itr = list_iterator_create(user.coord_accts); while ((coord = list_next(itr))) if (!strcasecmp(coord->name, slurmdb_assoc->acct)) break; list_iterator_destroy(itr); if (coord) goto is_user; bad_user: errno = ESLURM_ACCESS_DENIED; return SLURM_ERROR; } } is_user: if (set_usage_information(&my_usage_table, type, &start, &end) != SLURM_SUCCESS) { return SLURM_ERROR; } xfree(tmp); i=0; xstrfmtcat(tmp, "%s", usage_req_inx[i]); for(i=1; i<USAGE_COUNT; i++) { xstrfmtcat(tmp, ", %s", usage_req_inx[i]); } switch (type) { case DBD_GET_ASSOC_USAGE: query = xstrdup_printf( "select %s from \"%s_%s\" as t1, " "\"%s_%s\" as t2, \"%s_%s\" as t3 " "where (t1.time_start < %ld && t1.time_start >= %ld) " "&& t1.id_assoc=t2.id_assoc && t3.id_assoc=%d && " "t2.lft between t3.lft and t3.rgt " "order by t3.id_assoc, time_start;", tmp, cluster_name, my_usage_table, cluster_name, cluster_name, assoc_table, assoc_table, end, start, id); break; case DBD_GET_WCKEY_USAGE: query = xstrdup_printf( "select %s from \"%s_%s\" " "where (time_start < %ld && time_start >= %ld) " "&& id_wckey=%d order by id_wckey, time_start;", tmp, cluster_name, my_usage_table, end, start, id); break; default: error("Unknown usage type %d", type); return SLURM_ERROR; break; } xfree(tmp); 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); return SLURM_ERROR; } xfree(query); if (!(*my_list)) (*my_list) = list_create(slurmdb_destroy_accounting_rec); while ((row = mysql_fetch_row(result))) { slurmdb_accounting_rec_t *accounting_rec = xmalloc(sizeof(slurmdb_accounting_rec_t)); accounting_rec->id = slurm_atoul(row[USAGE_ID]); accounting_rec->period_start = slurm_atoul(row[USAGE_START]); accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]); accounting_rec->consumed_energy = slurm_atoull(row[USAGE_ENERGY]); list_append((*my_list), accounting_rec); } mysql_free_result(result); return rc; }
extern int as_mysql_add_coord(mysql_conn_t *mysql_conn, uint32_t uid, List acct_list, slurmdb_user_cond_t *user_cond) { char *query = NULL, *user = NULL, *acct = NULL; char *user_name = NULL, *txn_query = NULL; ListIterator itr, itr2; time_t now = time(NULL); int rc = SLURM_SUCCESS; slurmdb_user_rec_t *user_rec = NULL; if (!user_cond || !user_cond->assoc_cond || !user_cond->assoc_cond->user_list || !list_count(user_cond->assoc_cond->user_list) || !acct_list || !list_count(acct_list)) { error("we need something to add"); return SLURM_ERROR; } 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; slurmdb_coord_rec_t *coord = NULL; char *acct = NULL; 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 account coordinators"); return ESLURM_ACCESS_DENIED; } itr = list_iterator_create(acct_list); itr2 = list_iterator_create(user.coord_accts); while ((acct = list_next(itr))) { while ((coord = list_next(itr2))) { if (!xstrcasecmp(coord->name, acct)) break; } if (!coord) break; list_iterator_reset(itr2); } list_iterator_destroy(itr2); list_iterator_destroy(itr); if (!coord) { error("Coordinator %s(%d) tried to add another " "coordinator to an account they aren't " "coordinator over.", user.name, user.uid); return ESLURM_ACCESS_DENIED; } } user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(user_cond->assoc_cond->user_list); itr2 = list_iterator_create(acct_list); while ((user = list_next(itr))) { if (!user[0]) continue; while ((acct = list_next(itr2))) { if (!acct[0]) continue; if (query) xstrfmtcat(query, ", (%ld, %ld, '%s', '%s')", (long)now, (long)now, acct, user); else query = xstrdup_printf( "insert into %s (creation_time, " "mod_time, acct, user) values " "(%ld, %ld, '%s', '%s')", acct_coord_table, (long)now, (long)now, acct, user); if (txn_query) xstrfmtcat(txn_query, ", (%ld, %u, '%s', '%s', '%s')", (long)now, DBD_ADD_ACCOUNT_COORDS, user, user_name, acct); else xstrfmtcat(txn_query, "insert into %s " "(timestamp, action, name, " "actor, info) " "values (%ld, %u, '%s', " "'%s', '%s')", txn_table, (long)now, DBD_ADD_ACCOUNT_COORDS, user, user_name, acct); } list_iterator_reset(itr2); } xfree(user_name); list_iterator_destroy(itr); list_iterator_destroy(itr2); if (query) { xstrfmtcat(query, " on duplicate key update mod_time=%ld, " "deleted=0;%s", (long)now, txn_query); if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "query\n%s", query); rc = mysql_db_query(mysql_conn, query); xfree(query); xfree(txn_query); if (rc != SLURM_SUCCESS) { error("Couldn't add cluster hour rollup"); return rc; } /* get the update list set */ itr = list_iterator_create(user_cond->assoc_cond->user_list); while ((user = list_next(itr))) { user_rec = xmalloc(sizeof(slurmdb_user_rec_t)); user_rec->name = xstrdup(user); _get_user_coords(mysql_conn, user_rec); if (addto_update_list(mysql_conn->update_list, SLURMDB_ADD_COORD, user_rec) != SLURM_SUCCESS) slurmdb_destroy_user_rec(user_rec); } list_iterator_destroy(itr); } return SLURM_SUCCESS; }
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_assoc_rec); List wckey_list = list_create(slurmdb_destroy_wckey_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(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_assoc_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 (!xstrcmp(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 (!xstrcmp(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 ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list)) != SLURM_SUCCESS) error("Problem adding user associations"); } FREE_NULL_LIST(assoc_list); if (rc == SLURM_SUCCESS && list_count(wckey_list)) { if ((rc = as_mysql_add_wckeys(mysql_conn, uid, wckey_list)) != SLURM_SUCCESS) error("Problem adding user wckeys"); } FREE_NULL_LIST(wckey_list); return rc; }
/* The assoc_mgr locks should be unlocked before coming here. */ extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid, void *in, slurmdbd_msg_type_t type, time_t start, time_t end) { int rc = SLURM_SUCCESS; int is_admin=1; char *my_usage_table = NULL; slurmdb_assoc_rec_t *slurmdb_assoc = in; slurmdb_wckey_rec_t *slurmdb_wckey = in; char *username = NULL; uint16_t private_data = 0; List *my_list = NULL; char *cluster_name = NULL; char *id_str = NULL; if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; switch (type) { case DBD_GET_ASSOC_USAGE: if (!slurmdb_assoc->id) { error("We need an id to set data for getting usage"); return SLURM_ERROR; } id_str = xstrdup_printf("t3.id_assoc=%u", slurmdb_assoc->id); cluster_name = slurmdb_assoc->cluster; username = slurmdb_assoc->user; my_list = &slurmdb_assoc->accounting_list; my_usage_table = assoc_day_table; break; case DBD_GET_WCKEY_USAGE: if (!slurmdb_wckey->id) { error("We need an id to set data for getting usage"); return SLURM_ERROR; } id_str = xstrdup_printf("id=%d", slurmdb_wckey->id); cluster_name = slurmdb_wckey->cluster; username = slurmdb_wckey->user; my_list = &slurmdb_wckey->accounting_list; my_usage_table = wckey_day_table; break; case DBD_GET_CLUSTER_USAGE: rc = _get_cluster_usage(mysql_conn, uid, in, type, start, end); return rc; break; default: error("Unknown usage type %d", type); return SLURM_ERROR; break; } if (!cluster_name) { error("We need a cluster_name to set data for getting usage"); xfree(id_str); return SLURM_ERROR; } private_data = slurm_get_private_data(); if (private_data & PRIVATE_DATA_USAGE) { if (!(is_admin = is_user_min_admin_level( mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) { ListIterator itr = NULL; slurmdb_coord_rec_t *coord = NULL; slurmdb_user_rec_t user; bool is_coord; memset(&user, 0, sizeof(slurmdb_user_rec_t)); user.uid = uid; is_coord = is_user_any_coord(mysql_conn, &user); if (username && !strcmp(username, user.name)) goto is_user; if (type != DBD_GET_ASSOC_USAGE) goto bad_user; if (!slurmdb_assoc->acct) { debug("No account name given " "in association."); goto bad_user; } if (!is_coord) { debug4("This user is not a coordinator."); goto bad_user; } /* Existance of user.coord_accts is checked in is_user_any_coord. */ itr = list_iterator_create(user.coord_accts); while ((coord = list_next(itr))) if (!strcasecmp(coord->name, slurmdb_assoc->acct)) break; list_iterator_destroy(itr); if (coord) goto is_user; bad_user: errno = ESLURM_ACCESS_DENIED; xfree(id_str); return SLURM_ERROR; } } is_user: if (set_usage_information(&my_usage_table, type, &start, &end) != SLURM_SUCCESS) { xfree(id_str); return SLURM_ERROR; } _get_object_usage(mysql_conn, type, my_usage_table, cluster_name, id_str, start, end, my_list); xfree(id_str); return rc; }