static int _reset_default_wckey(mysql_conn_t *mysql_conn, slurmdb_wckey_rec_t *wckey) { time_t now = time(NULL); int rc = SLURM_SUCCESS; char *query = NULL; MYSQL_RES *result = NULL; MYSQL_ROW row; if ((wckey->is_def != 1) || !wckey->cluster || !wckey->user || !wckey->name) return SLURM_ERROR; xstrfmtcat(query, "update \"%s_%s\" set is_def=0, mod_time=%ld " "where (user='******' && wckey_name!='%s' && is_def=1);" "select id_wckey from \"%s_%s\" " "where (user='******' && wckey_name!='%s' && is_def=1);", wckey->cluster, wckey_table, (long)now, wckey->user, wckey->name, wckey->cluster, wckey_table, wckey->user, wckey->name); 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, 1))) { xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); while ((row = mysql_fetch_row(result))) { slurmdb_wckey_rec_t *mod_wckey = xmalloc(sizeof(slurmdb_wckey_rec_t)); slurmdb_init_wckey_rec(mod_wckey, 0); mod_wckey->id = slurm_atoul(row[0]); mod_wckey->is_def = 0; if (addto_update_list(mysql_conn->update_list, SLURMDB_MODIFY_WCKEY, mod_wckey) != SLURM_SUCCESS) { slurmdb_destroy_wckey_rec(mod_wckey); error("couldn't add to the update list"); rc = SLURM_ERROR; break; } } mysql_free_result(result); end_it: return rc; }
extern int as_mysql_add_feds_to_update_list(mysql_conn_t *mysql_conn) { int rc = SLURM_ERROR; List feds = as_mysql_get_federations(mysql_conn, 0, NULL); /* Even if there are no feds, need to send an empty list for the case * that all feds were removed. The controller needs to know that it was * removed from a federation. */ if (feds && ((rc = addto_update_list(mysql_conn->update_list, SLURMDB_UPDATE_FEDS, feds)) != SLURM_SUCCESS)) { FREE_NULL_LIST(feds); } return rc; }
/* * as_pg_remove_clusters - remove clusters * * IN pg_conn: database connection * IN uid: user performing the remove operation * IN cluster_cond: clusters to remove * RET: list of clusters removed */ extern List as_pg_remove_clusters(pgsql_conn_t *pg_conn, uint32_t uid, slurmdb_cluster_cond_t *cluster_cond) { DEF_VARS; List ret_list = NULL, job_list = NULL; int rc = SLURM_SUCCESS, has_jobs; char *cond = NULL, *user_name = NULL; time_t now = time(NULL); if(!cluster_cond) { error("as/pg: remove_clusters: we need something to remove"); return NULL; } if(check_db_connection(pg_conn) != SLURM_SUCCESS) return NULL; concat_cond_list(cluster_cond->cluster_list, NULL, "name", &cond); if(!cond) { error("as/pg: remove_clusters: nothing to remove"); return NULL; } query = xstrdup_printf("SELECT name FROM %s WHERE deleted=0 %s;", cluster_table, cond); xfree(cond); result = DEF_QUERY_RET; if (!result) { error("as/pg: remove_clusters: failed to get cluster names"); return NULL; } ret_list = list_create(slurm_destroy_char); if (PQntuples(result) == 0) { PQclear(result); errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything"); /* XXX: if we return NULL, test21.27 will fail to execute */ return ret_list; } user_name = uid_to_string((uid_t)uid); rc = 0; FOR_EACH_ROW { char *cluster = ROW(0); job_list = _get_cluster_running_jobs(pg_conn, cluster); if (job_list) break; has_jobs = _cluster_has_jobs(pg_conn, cluster); if (!has_jobs) query = xstrdup_printf( "DELETE FROM %s WHERE creation_time>%ld AND " "name='%s';", cluster_table, (now - DELETE_SEC_BACK), cluster); xstrfmtcat(query, "UPDATE %s SET mod_time=%ld, deleted=1 WHERE " "deleted=0 AND name='%s';", cluster_table, now, cluster); xstrfmtcat(query, "INSERT INTO %s (timestamp, action, name, actor) " "VALUES (%ld, %d, '%s', '%s');", txn_table, now, (int)DBD_REMOVE_CLUSTERS, cluster, user_name); rc = DEF_QUERY_RET_RC; if (rc != SLURM_SUCCESS) break; rc = _remove_cluster_tables(pg_conn, cluster); if (rc != SLURM_SUCCESS) break; list_append(ret_list, xstrdup(cluster)); addto_update_list(pg_conn->update_list, SLURMDB_REMOVE_CLUSTER, xstrdup(cluster)); pg_conn->cluster_changed = 1; } END_EACH_ROW; PQclear(result); if (job_list) { reset_pgsql_conn(pg_conn); list_destroy(ret_list); error("as/pg: remove_clusters: jobs running on cluster"); errno = ESLURM_JOBS_RUNNING_ON_ASSOC; return job_list; } if (rc != SLURM_SUCCESS) { reset_pgsql_conn(pg_conn); list_destroy(ret_list); ret_list = NULL; } return ret_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 List as_mysql_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_user_cond_t *user_cond) { ListIterator itr = NULL; List ret_list = NULL; List coord_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *extra = NULL, *query = NULL, *name_char = NULL, *assoc_char = NULL; time_t now = time(NULL); char *user_name = NULL; int set = 0; MYSQL_RES *result = NULL; MYSQL_ROW row; slurmdb_user_cond_t user_coord_cond; slurmdb_association_cond_t assoc_cond; slurmdb_wckey_cond_t wckey_cond; bool jobs_running = 0; if (!user_cond) { error("we need something to remove"); return NULL; } if (check_connection(mysql_conn) != SLURM_SUCCESS) 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 (!object[0]) continue; if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } ret_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond); if (user_cond->admin_level != SLURMDB_ADMIN_NOTSET) { xstrfmtcat(extra, " && admin_level=%u", user_cond->admin_level); } if (!extra && !ret_list) { error("Nothing to remove"); return NULL; } else if (!extra) { /* means we got a ret_list and don't need to look at the user_table. */ goto no_user_table; } /* Only handle this if we need to actually query the user_table. If a request comes in stating they want to remove all users with default account of whatever then that doesn't deal with the user_table. */ query = xstrdup_printf("select name from %s where deleted=0 %s;", user_table, extra); xfree(extra); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); return NULL; } if (!ret_list) ret_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) slurm_addto_char_list(ret_list, row[0]); mysql_free_result(result); no_user_table: if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything\n%s", query); xfree(query); return ret_list; } xfree(query); memset(&user_coord_cond, 0, sizeof(slurmdb_user_cond_t)); memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); /* we do not need to free the objects we put in here since they are also placed in a list that will be freed */ assoc_cond.user_list = list_create(NULL); user_coord_cond.assoc_cond = &assoc_cond; itr = list_iterator_create(ret_list); while ((object = list_next(itr))) { slurmdb_user_rec_t *user_rec = xmalloc(sizeof(slurmdb_user_rec_t)); list_append(assoc_cond.user_list, object); if (name_char) { xstrfmtcat(name_char, " || name='%s'", object); xstrfmtcat(assoc_char, " || t2.user='******'", object); } else { xstrfmtcat(name_char, "name='%s'", object); xstrfmtcat(assoc_char, "t2.user='******'", object); } user_rec->name = xstrdup(object); if (addto_update_list(mysql_conn->update_list, SLURMDB_REMOVE_USER, user_rec) != SLURM_SUCCESS) slurmdb_destroy_user_rec(user_rec); } list_iterator_destroy(itr); /* We need to remove these accounts from the coord's that have it */ coord_list = as_mysql_remove_coord( mysql_conn, uid, NULL, &user_coord_cond); if (coord_list) list_destroy(coord_list); /* We need to remove these users from the wckey table */ memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t)); wckey_cond.user_list = assoc_cond.user_list; coord_list = as_mysql_remove_wckeys(mysql_conn, uid, &wckey_cond); if (coord_list) list_destroy(coord_list); list_destroy(assoc_cond.user_list); user_name = uid_to_string((uid_t) uid); slurm_mutex_lock(&as_mysql_cluster_list_lock); itr = list_iterator_create(as_mysql_cluster_list); while ((object = list_next(itr))) { if ((rc = remove_common(mysql_conn, DBD_REMOVE_USERS, now, user_name, user_table, name_char, assoc_char, object, ret_list, &jobs_running)) != SLURM_SUCCESS) break; } list_iterator_destroy(itr); slurm_mutex_unlock(&as_mysql_cluster_list_lock); xfree(user_name); xfree(name_char); if (rc == SLURM_ERROR) { list_destroy(ret_list); xfree(assoc_char); return NULL; } query = xstrdup_printf( "update %s as t2 set deleted=1, mod_time=%ld where %s", acct_coord_table, (long)now, assoc_char); xfree(assoc_char); rc = mysql_db_query(mysql_conn, query); xfree(query); if (rc != SLURM_SUCCESS) { error("Couldn't remove user coordinators"); list_destroy(ret_list); return NULL; } if (jobs_running) errno = ESLURM_JOBS_RUNNING_ON_ASSOC; else errno = SLURM_SUCCESS; return ret_list; }
extern List as_mysql_modify_users(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_user_cond_t *user_cond, slurmdb_user_rec_t *user) { ListIterator itr = NULL; List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL; time_t now = time(NULL); char *user_name = NULL; int set = 0; MYSQL_RES *result = NULL; MYSQL_ROW row; if (!user_cond || !user) { error("we need something to change"); return NULL; } if (check_connection(mysql_conn) != SLURM_SUCCESS) 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); ret_list = _get_other_user_names_to_mod(mysql_conn, uid, user_cond); if (user->name) xstrfmtcat(vals, ", name='%s'", user->name); if (user->admin_level != SLURMDB_ADMIN_NOTSET) xstrfmtcat(vals, ", admin_level=%u", user->admin_level); if ((!extra && !ret_list) || (!vals && !user->default_acct && !user->default_wckey)) { errno = SLURM_NO_CHANGE_IN_DATA; error("Nothing to change"); return NULL; } if (!extra) { /* means we got a ret_list and don't need to look at the user_table. */ goto no_user_table; } query = xstrdup_printf( "select distinct name from %s where deleted=0 %s;", user_table, extra); xfree(extra); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); if (ret_list) list_destroy(ret_list); return NULL; } if (!ret_list) ret_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) { slurmdb_user_rec_t *user_rec = NULL; object = row[0]; slurm_addto_char_list(ret_list, object); if (!name_char) xstrfmtcat(name_char, "(name='%s'", object); else xstrfmtcat(name_char, " || name='%s'", object); user_rec = xmalloc(sizeof(slurmdb_user_rec_t)); if (!user->name) user_rec->name = xstrdup(object); else { user_rec->name = xstrdup(user->name); user_rec->old_name = xstrdup(object); if (_change_user_name(mysql_conn, user_rec) != SLURM_SUCCESS) break; } user_rec->admin_level = user->admin_level; if (addto_update_list(mysql_conn->update_list, SLURMDB_MODIFY_USER, user_rec) != SLURM_SUCCESS) slurmdb_destroy_user_rec(user_rec); } mysql_free_result(result); no_user_table: if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything\n%s", query); xfree(vals); xfree(query); return ret_list; } else if (user->name && (list_count(ret_list) != 1)) { errno = ESLURM_ONE_CHANGE; xfree(vals); xfree(query); if (ret_list) list_destroy(ret_list); return NULL; } xfree(query); if (name_char && vals) { xstrcat(name_char, ")"); user_name = uid_to_string((uid_t) uid); rc = modify_common(mysql_conn, DBD_MODIFY_USERS, now, user_name, user_table, name_char, vals, NULL); xfree(user_name); } xfree(name_char); xfree(vals); if (rc == SLURM_ERROR) { error("Couldn't modify users"); list_destroy(ret_list); ret_list = NULL; } if (user->default_acct) { slurmdb_association_cond_t assoc_cond; slurmdb_association_rec_t assoc; List tmp_list = NULL; memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t)); slurmdb_init_association_rec(&assoc, 0); assoc.is_def = 1; assoc_cond.acct_list = list_create(NULL); list_append(assoc_cond.acct_list, user->default_acct); assoc_cond.user_list = ret_list; if (user_cond->assoc_cond && user_cond->assoc_cond->cluster_list) assoc_cond.cluster_list = user_cond->assoc_cond->cluster_list; tmp_list = as_mysql_modify_assocs(mysql_conn, uid, &assoc_cond, &assoc); list_destroy(assoc_cond.acct_list); if (!tmp_list) { list_destroy(ret_list); ret_list = NULL; goto end_it; } /* char *names = NULL; */ /* ListIterator itr = list_iterator_create(tmp_list); */ /* while ((names = list_next(itr))) { */ /* info("%s", names); */ /* } */ /* list_iterator_destroy(itr); */ list_destroy(tmp_list); } if (user->default_wckey) { slurmdb_wckey_cond_t wckey_cond; slurmdb_wckey_rec_t wckey; List tmp_list = NULL; memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t)); slurmdb_init_wckey_rec(&wckey, 0); wckey.is_def = 1; wckey_cond.name_list = list_create(NULL); list_append(wckey_cond.name_list, user->default_wckey); wckey_cond.user_list = ret_list; if (user_cond->assoc_cond && user_cond->assoc_cond->cluster_list) wckey_cond.cluster_list = user_cond->assoc_cond->cluster_list; tmp_list = as_mysql_modify_wckeys(mysql_conn, uid, &wckey_cond, &wckey); list_destroy(wckey_cond.name_list); if (!tmp_list) { list_destroy(ret_list); ret_list = NULL; goto end_it; } /* char *names = NULL; */ /* ListIterator itr = list_iterator_create(tmp_list); */ /* while ((names = list_next(itr))) { */ /* info("%s", names); */ /* } */ /* list_iterator_destroy(itr); */ list_destroy(tmp_list); } end_it: return ret_list; }
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; 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); debug3("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, 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_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_modify_qos(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_qos_cond_t *qos_cond, slurmdb_qos_rec_t *qos) { ListIterator itr = NULL; List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL; time_t now = time(NULL); char *user_name = NULL; int set = 0, i; MYSQL_RES *result = NULL; MYSQL_ROW row; char *tmp_char1=NULL, *tmp_char2=NULL; bitstr_t *preempt_bitstr = NULL; char *added_preempt = NULL; uint32_t qos_cnt; assoc_mgr_lock_t locks = { NO_LOCK, NO_LOCK, READ_LOCK, NO_LOCK, NO_LOCK, NO_LOCK, NO_LOCK }; if (!qos_cond || !qos) { 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_SUPER_USER)) { errno = ESLURM_ACCESS_DENIED; return NULL; } xstrcat(extra, "where deleted=0"); if (qos_cond->description_list && list_count(qos_cond->description_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_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 (qos_cond->id_list && list_count(qos_cond->id_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->id_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "id='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (qos_cond->name_list && list_count(qos_cond->name_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->name_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } _setup_qos_limits(qos, &tmp_char1, &tmp_char2, &vals, &added_preempt, 0); assoc_mgr_lock(&locks); qos_cnt = g_qos_count; assoc_mgr_unlock(&locks); if (added_preempt) { preempt_bitstr = bit_alloc(qos_cnt); bit_unfmt(preempt_bitstr, added_preempt+1); xfree(added_preempt); } xfree(tmp_char1); xfree(tmp_char2); if (!extra || !vals) { errno = SLURM_NO_CHANGE_IN_DATA; FREE_NULL_BITMAP(preempt_bitstr); error("Nothing to change"); return NULL; } object = xstrdup(mqos_req_inx[0]); for (i = 1; i < MQOS_COUNT; i++) xstrfmtcat(object, ", %s", mqos_req_inx[i]); query = xstrdup_printf("select %s from %s %s;", object, qos_table, extra); xfree(extra); xfree(object); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); FREE_NULL_BITMAP(preempt_bitstr); return NULL; } rc = 0; ret_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) { slurmdb_qos_rec_t *qos_rec = NULL; uint32_t id = slurm_atoul(row[MQOS_ID]); if (preempt_bitstr) { if (_preemption_loop(mysql_conn, id, preempt_bitstr)) break; } object = xstrdup(row[MQOS_NAME]); list_append(ret_list, object); if (!rc) { xstrfmtcat(name_char, "(name='%s'", object); rc = 1; } else { xstrfmtcat(name_char, " || name='%s'", object); } qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t)); qos_rec->name = xstrdup(object); qos_rec->id = id; qos_rec->flags = qos->flags; qos_rec->grace_time = qos->grace_time; mod_tres_str(&qos_rec->grp_tres, qos->grp_tres, row[MQOS_GT], NULL, "grp_tres", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->grp_tres_mins, qos->grp_tres_mins, row[MQOS_GTM], NULL, "grp_tres_mins", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->grp_tres_run_mins, qos->grp_tres_run_mins, row[MQOS_GTRM], NULL, "grp_tres_run_mins", &vals, qos_rec->id, 0); qos_rec->grp_jobs = qos->grp_jobs; qos_rec->grp_submit_jobs = qos->grp_submit_jobs; qos_rec->grp_wall = qos->grp_wall; mod_tres_str(&qos_rec->max_tres_pa, qos->max_tres_pa, row[MQOS_MTPA], NULL, "max_tres_pa", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_pj, qos->max_tres_pj, row[MQOS_MTPJ], NULL, "max_tres_pj", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_pn, qos->max_tres_pn, row[MQOS_MTPN], NULL, "max_tres_pn", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_pu, qos->max_tres_pu, row[MQOS_MTPU], NULL, "max_tres_pu", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_mins_pj, qos->max_tres_mins_pj, row[MQOS_MTMPJ], NULL, "max_tres_mins_pj", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_run_mins_pa, qos->max_tres_run_mins_pa, row[MQOS_MTRM], NULL, "max_tres_run_mins_pa", &vals, qos_rec->id, 0); mod_tres_str(&qos_rec->max_tres_run_mins_pu, qos->max_tres_run_mins_pu, row[MQOS_MTRM], NULL, "max_tres_run_mins_pu", &vals, qos_rec->id, 0); qos_rec->max_jobs_pa = qos->max_jobs_pa; qos_rec->max_jobs_pu = qos->max_jobs_pu; qos_rec->max_submit_jobs_pa = qos->max_submit_jobs_pa; qos_rec->max_submit_jobs_pu = qos->max_submit_jobs_pu; qos_rec->max_wall_pj = qos->max_wall_pj; mod_tres_str(&qos_rec->min_tres_pj, qos->min_tres_pj, row[MQOS_MITPJ], NULL, "min_tres_pj", &vals, qos_rec->id, 0); qos_rec->preempt_mode = qos->preempt_mode; qos_rec->priority = qos->priority; if (qos->preempt_list) { ListIterator new_preempt_itr = list_iterator_create(qos->preempt_list); char *new_preempt = NULL; bool cleared = 0; qos_rec->preempt_bitstr = bit_alloc(qos_cnt); if (row[MQOS_PREEMPT] && row[MQOS_PREEMPT][0]) bit_unfmt(qos_rec->preempt_bitstr, row[MQOS_PREEMPT]+1); while ((new_preempt = list_next(new_preempt_itr))) { if (new_preempt[0] == '-') { bit_clear(qos_rec->preempt_bitstr, atol(new_preempt+1)); } else if (new_preempt[0] == '+') { bit_set(qos_rec->preempt_bitstr, atol(new_preempt+1)); } else { if (!cleared) { cleared = 1; bit_nclear( qos_rec->preempt_bitstr, 0, qos_cnt-1); } bit_set(qos_rec->preempt_bitstr, atol(new_preempt)); } } list_iterator_destroy(new_preempt_itr); } qos_rec->usage_factor = qos->usage_factor; qos_rec->usage_thres = qos->usage_thres; if (addto_update_list(mysql_conn->update_list, SLURMDB_MODIFY_QOS, qos_rec) != SLURM_SUCCESS) slurmdb_destroy_qos_rec(qos_rec); } mysql_free_result(result); FREE_NULL_BITMAP(preempt_bitstr); if (row) { xfree(vals); xfree(name_char); xfree(query); FREE_NULL_LIST(ret_list); ret_list = NULL; errno = ESLURM_QOS_PREEMPTION_LOOP; return ret_list; } if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; if (debug_flags & DEBUG_FLAG_DB_QOS) DB_DEBUG(mysql_conn->conn, "didn't effect anything\n%s", query); xfree(vals); xfree(query); return ret_list; } xfree(query); xstrcat(name_char, ")"); user_name = uid_to_string((uid_t) uid); rc = modify_common(mysql_conn, DBD_MODIFY_QOS, now, user_name, qos_table, name_char, vals, NULL); xfree(user_name); xfree(name_char); xfree(vals); if (rc == SLURM_ERROR) { error("Couldn't modify qos"); FREE_NULL_LIST(ret_list); ret_list = NULL; } return ret_list; }
extern List as_mysql_modify_qos(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_qos_cond_t *qos_cond, slurmdb_qos_rec_t *qos) { ListIterator itr = NULL; List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL; time_t now = time(NULL); char *user_name = NULL; int set = 0; MYSQL_RES *result = NULL; MYSQL_ROW row; char *tmp_char1=NULL, *tmp_char2=NULL; bitstr_t *preempt_bitstr = NULL; char *added_preempt = NULL; if (!qos_cond || !qos) { error("we need something to change"); return NULL; } if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; xstrcat(extra, "where deleted=0"); if (qos_cond->description_list && list_count(qos_cond->description_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_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 (qos_cond->id_list && list_count(qos_cond->id_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->id_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "id='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (qos_cond->name_list && list_count(qos_cond->name_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->name_list); while ((object = list_next(itr))) { if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } _setup_qos_limits(qos, &tmp_char1, &tmp_char2, &vals, &added_preempt, 0); if (added_preempt) { preempt_bitstr = bit_alloc(g_qos_count); bit_unfmt(preempt_bitstr, added_preempt+1); xfree(added_preempt); } xfree(tmp_char1); xfree(tmp_char2); if (!extra || !vals) { errno = SLURM_NO_CHANGE_IN_DATA; FREE_NULL_BITMAP(preempt_bitstr); error("Nothing to change"); return NULL; } query = xstrdup_printf("select name, preempt, id from %s %s;", qos_table, extra); xfree(extra); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); FREE_NULL_BITMAP(preempt_bitstr); return NULL; } rc = 0; ret_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) { slurmdb_qos_rec_t *qos_rec = NULL; uint32_t id = slurm_atoul(row[2]); if (preempt_bitstr) { if (_preemption_loop(mysql_conn, id, preempt_bitstr)) break; } object = xstrdup(row[0]); list_append(ret_list, object); if (!rc) { xstrfmtcat(name_char, "(name='%s'", object); rc = 1; } else { xstrfmtcat(name_char, " || name='%s'", object); } qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t)); qos_rec->name = xstrdup(object); qos_rec->id = id; qos_rec->flags = qos->flags; qos_rec->grp_cpus = qos->grp_cpus; qos_rec->grace_time = qos->grace_time; qos_rec->grp_cpu_mins = qos->grp_cpu_mins; qos_rec->grp_cpu_run_mins = qos->grp_cpu_run_mins; qos_rec->grp_jobs = qos->grp_jobs; qos_rec->grp_nodes = qos->grp_nodes; qos_rec->grp_submit_jobs = qos->grp_submit_jobs; qos_rec->grp_wall = qos->grp_wall; qos_rec->max_cpus_pj = qos->max_cpus_pj; qos_rec->max_cpu_mins_pj = qos->max_cpu_mins_pj; qos_rec->max_cpu_run_mins_pu = qos->max_cpu_run_mins_pu; qos_rec->max_jobs_pu = qos->max_jobs_pu; qos_rec->max_nodes_pj = qos->max_nodes_pj; qos_rec->max_submit_jobs_pu = qos->max_submit_jobs_pu; qos_rec->max_wall_pj = qos->max_wall_pj; qos_rec->preempt_mode = qos->preempt_mode; qos_rec->priority = qos->priority; if (qos->preempt_list) { ListIterator new_preempt_itr = list_iterator_create(qos->preempt_list); char *new_preempt = NULL; qos_rec->preempt_bitstr = bit_alloc(g_qos_count); if (row[1] && row[1][0]) bit_unfmt(qos_rec->preempt_bitstr, row[1]+1); while ((new_preempt = list_next(new_preempt_itr))) { bool cleared = 0; if (new_preempt[0] == '-') { bit_clear(qos_rec->preempt_bitstr, atol(new_preempt+1)); } else if (new_preempt[0] == '+') { bit_set(qos_rec->preempt_bitstr, atol(new_preempt+1)); } else { if (!cleared) { cleared = 1; bit_nclear( qos_rec->preempt_bitstr, 0, g_qos_count-1); } bit_set(qos_rec->preempt_bitstr, atol(new_preempt)); } } list_iterator_destroy(new_preempt_itr); } qos_rec->usage_factor = qos->usage_factor; qos_rec->usage_thres = qos->usage_thres; if (addto_update_list(mysql_conn->update_list, SLURMDB_MODIFY_QOS, qos_rec) != SLURM_SUCCESS) slurmdb_destroy_qos_rec(qos_rec); } mysql_free_result(result); FREE_NULL_BITMAP(preempt_bitstr); if (row) { xfree(vals); xfree(name_char); xfree(query); list_destroy(ret_list); ret_list = NULL; errno = ESLURM_QOS_PREEMPTION_LOOP; return ret_list; } if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything\n%s", query); xfree(vals); xfree(query); return ret_list; } xfree(query); xstrcat(name_char, ")"); user_name = uid_to_string((uid_t) uid); rc = modify_common(mysql_conn, DBD_MODIFY_QOS, now, user_name, qos_table, name_char, vals, NULL); xfree(user_name); xfree(name_char); xfree(vals); if (rc == SLURM_ERROR) { error("Couldn't modify qos"); list_destroy(ret_list); ret_list = NULL; } return ret_list; }
extern int as_mysql_add_qos(mysql_conn_t *mysql_conn, uint32_t uid, List qos_list) { ListIterator itr = NULL; int rc = SLURM_SUCCESS; slurmdb_qos_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; char *added_preempt = NULL; if (check_connection(mysql_conn) != SLURM_SUCCESS) return ESLURM_DB_CONNECTION; user_name = uid_to_string((uid_t) uid); itr = list_iterator_create(qos_list); while ((object = list_next(itr))) { if (!object->name || !object->name[0]) { error("We need a qos name to add."); rc = SLURM_ERROR; continue; } xstrcat(cols, "creation_time, mod_time, name"); xstrfmtcat(vals, "%ld, %ld, '%s'", now, now, object->name); xstrfmtcat(extra, ", mod_time=%ld", now); _setup_qos_limits(object, &cols, &vals, &extra, &added_preempt, 1); if (added_preempt) { object->preempt_bitstr = bit_alloc(g_qos_count); bit_unfmt(object->preempt_bitstr, added_preempt+1); xfree(added_preempt); } xstrfmtcat(query, "insert into %s (%s) values (%s) " "on duplicate key update deleted=0, " "id=LAST_INSERT_ID(id)%s;", qos_table, cols, vals, extra); debug3("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); object->id = mysql_db_insert_ret_id(mysql_conn, query); xfree(query); if (!object->id) { error("Couldn't add qos %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) " "values (%ld, %u, '%s', '%s', '%s');", txn_table, now, DBD_ADD_QOS, object->name, user_name, tmp_extra); 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_QOS, object) == SLURM_SUCCESS) list_remove(itr); added++; } } list_iterator_destroy(itr); xfree(user_name); if (!added) { reset_mysql_conn(mysql_conn); } 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; }
static int _cluster_modify_wckeys(mysql_conn_t *mysql_conn, slurmdb_wckey_rec_t *wckey, char *cluster_name, char *extra, char *vals, char *user_name, List ret_list) { int rc = SLURM_SUCCESS; MYSQL_RES *result = NULL; MYSQL_ROW row; char *wckey_char = NULL; time_t now = time(NULL); char *query = NULL; query = xstrdup_printf("select t1.id_wckey, t1.wckey_name, t1.user " "from \"%s_%s\" as t1%s;", cluster_name, wckey_table, extra); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); return SLURM_ERROR; } /* This key doesn't exist on this cluster, that is ok. */ if (!mysql_num_rows(result)) return SLURM_SUCCESS; while ((row = mysql_fetch_row(result))) { slurmdb_wckey_rec_t *wckey_rec = NULL; char *object = xstrdup_printf( "C = %-10s W = %-20s U = %-9s", cluster_name, row[1], row[2]); list_append(ret_list, object); if (!wckey_char) xstrfmtcat(wckey_char, "id_wckey='%s'", row[0]); else xstrfmtcat(wckey_char, " || id_wckey='%s'", row[0]); wckey_rec = xmalloc(sizeof(slurmdb_wckey_rec_t)); /* we only need id and cluster when removing no real need to init */ wckey_rec->id = slurm_atoul(row[0]); wckey_rec->cluster = xstrdup(cluster_name); wckey_rec->is_def = wckey->is_def; if (addto_update_list(mysql_conn->update_list, SLURMDB_MODIFY_WCKEY, wckey_rec) != SLURM_SUCCESS) slurmdb_destroy_wckey_rec(wckey_rec); if (wckey->is_def == 1) { /* Use fresh one here so we don't have to worry about dealing with bad values. */ slurmdb_wckey_rec_t tmp_wckey; slurmdb_init_wckey_rec(&tmp_wckey, 0); tmp_wckey.is_def = 1; tmp_wckey.cluster = cluster_name; tmp_wckey.name = row[1]; tmp_wckey.user = row[2]; if ((rc = _reset_default_wckey(mysql_conn, &tmp_wckey)) != SLURM_SUCCESS) break; } } mysql_free_result(result); if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; if (debug_flags & DEBUG_FLAG_DB_WCKEY) DB_DEBUG(mysql_conn->conn, "didn't effect anything\n%s", query); xfree(query); xfree(wckey_char); return SLURM_SUCCESS; } xfree(query); rc = modify_common(mysql_conn, DBD_MODIFY_WCKEYS, now, user_name, wckey_table, wckey_char, vals, cluster_name); xfree(wckey_char); return rc; }
static int _cluster_remove_wckeys(mysql_conn_t *mysql_conn, char *extra, char *cluster_name, char *user_name, List ret_list) { int rc = SLURM_SUCCESS; MYSQL_RES *result = NULL; MYSQL_ROW row; char *assoc_char = NULL; time_t now = time(NULL); char *query = xstrdup_printf("select t1.id_wckey, t1.wckey_name " "from \"%s_%s\" as t1%s;", cluster_name, wckey_table, extra); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); return SLURM_ERROR; } if (!mysql_num_rows(result)) { mysql_free_result(result); xfree(query); return SLURM_SUCCESS; } while ((row = mysql_fetch_row(result))) { slurmdb_wckey_rec_t *wckey_rec = NULL; list_append(ret_list, xstrdup(row[1])); if (!assoc_char) xstrfmtcat(assoc_char, "id_wckey='%s'", row[0]); else xstrfmtcat(assoc_char, " || id_wckey='%s'", row[0]); wckey_rec = xmalloc(sizeof(slurmdb_wckey_rec_t)); /* we only need id and cluster when removing no real need to init */ wckey_rec->id = slurm_atoul(row[0]); wckey_rec->cluster = xstrdup(cluster_name); if (addto_update_list(mysql_conn->update_list, SLURMDB_REMOVE_WCKEY, wckey_rec) != SLURM_SUCCESS) slurmdb_destroy_wckey_rec(wckey_rec); } mysql_free_result(result); if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; if (debug_flags & DEBUG_FLAG_DB_WCKEY) DB_DEBUG(mysql_conn->conn, "didn't effect anything\n%s", query); xfree(query); xfree(assoc_char); return SLURM_SUCCESS; } xfree(query); rc = remove_common(mysql_conn, DBD_REMOVE_WCKEYS, now, user_name, wckey_table, assoc_char, assoc_char, cluster_name, NULL, NULL); xfree(assoc_char); if (rc == SLURM_ERROR) { list_destroy(ret_list); return SLURM_ERROR; } return SLURM_SUCCESS; }
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 List as_mysql_remove_clusters(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_cluster_cond_t *cluster_cond) { ListIterator itr = NULL; List ret_list = NULL; List tmp_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *extra = NULL, *query = NULL, *cluster_name = NULL, *name_char = NULL, *assoc_char = NULL; time_t now = time(NULL); char *user_name = NULL; slurmdb_wckey_cond_t wckey_cond; MYSQL_RES *result = NULL; MYSQL_ROW row; bool jobs_running = 0; if (!cluster_cond) { 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_SUPER_USER)) { errno = ESLURM_ACCESS_DENIED; return NULL; } /* force to only do non-deleted clusters */ cluster_cond->with_deleted = 0; _setup_cluster_cond_limits(cluster_cond, &extra); if (!extra) { error("Nothing to remove"); return NULL; } query = xstrdup_printf("select name from %s%s;", cluster_table, extra); xfree(extra); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); return NULL; } rc = 0; ret_list = list_create(slurm_destroy_char); if (!mysql_num_rows(result)) { mysql_free_result(result); errno = SLURM_NO_CHANGE_IN_DATA; if (debug_flags & DEBUG_FLAG_DB_ASSOC) DB_DEBUG(mysql_conn->conn, "didn't effect anything\n%s", query); xfree(query); return ret_list; } xfree(query); assoc_char = xstrdup_printf("t2.acct='root'"); user_name = uid_to_string((uid_t) uid); while ((row = mysql_fetch_row(result))) { char *object = xstrdup(row[0]); if (!jobs_running) list_append(ret_list, object); xfree(name_char); xstrfmtcat(name_char, "name='%s'", object); if (jobs_running) xfree(object); /* We should not need to delete any cluster usage just set it * to deleted */ xstrfmtcat(query, "update \"%s_%s\" set time_end=%ld where time_end=0;" "update \"%s_%s\" set mod_time=%ld, deleted=1;" "update \"%s_%s\" set mod_time=%ld, deleted=1;" "update \"%s_%s\" set mod_time=%ld, deleted=1;", object, event_table, now, object, cluster_day_table, now, object, cluster_hour_table, now, object, cluster_month_table, now); if ((rc = remove_common(mysql_conn, DBD_REMOVE_CLUSTERS, now, user_name, cluster_table, name_char, assoc_char, object, ret_list, &jobs_running)) != SLURM_SUCCESS) break; } mysql_free_result(result); xfree(user_name); xfree(name_char); xfree(assoc_char); if (rc != SLURM_SUCCESS) { FREE_NULL_LIST(ret_list); return NULL; } if (!jobs_running) { 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); if (rc != SLURM_SUCCESS) { reset_mysql_conn(mysql_conn); FREE_NULL_LIST(ret_list); return NULL; } /* We need to remove these clusters from the wckey table */ memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t)); wckey_cond.cluster_list = ret_list; tmp_list = as_mysql_remove_wckeys(mysql_conn, uid, &wckey_cond); FREE_NULL_LIST(tmp_list); itr = list_iterator_create(ret_list); while ((object = list_next(itr))) { if ((rc = remove_cluster_tables(mysql_conn, object)) != SLURM_SUCCESS) break; cluster_name = xstrdup(object); if (addto_update_list(mysql_conn->update_list, SLURMDB_REMOVE_CLUSTER, cluster_name) != SLURM_SUCCESS) xfree(cluster_name); } list_iterator_destroy(itr); if (rc != SLURM_SUCCESS) { reset_mysql_conn(mysql_conn); FREE_NULL_LIST(ret_list); errno = rc; return NULL; } errno = SLURM_SUCCESS; } else errno = ESLURM_JOBS_RUNNING_ON_ASSOC; return ret_list; }
/* * handle related associations: * 1. mark assoc usages as deleted * 2. delete assocs that does not has job * 3. mark other assocs as deleted * assoc_cond format: "t2.acct=name OR t2.acct=name..." */ static int _cluster_remove_acct_assoc(pgsql_conn_t *pg_conn, char *cluster, time_t now, char *assoc_cond, int has_jobs) { DEF_VARS; slurmdb_association_rec_t *rem_assoc = NULL; char *assoc_char = NULL; int rc = SLURM_SUCCESS; uint32_t smallest_lft = 0xFFFFFFFF, lft; query = xstrdup_printf ( "SELECT DISTINCT t1.id_assoc,t1.lft FROM %s.%s AS t1, %s.%s AS t2 " "WHERE t1.deleted=0 AND t2.deleted=0 AND (%s) AND " "t1.creation_time>%d " "AND (t1.lft BETWEEN t2.lft AND t2.rgt);", cluster, assoc_table, cluster, assoc_table, assoc_cond, (int)(now - DELETE_SEC_BACK)); result = DEF_QUERY_RET; if (!result) return SLURM_ERROR; if (PQntuples(result) == 0) { PQclear(result); return SLURM_SUCCESS; } FOR_EACH_ROW { if (assoc_char) xstrfmtcat(assoc_char, " OR id_assoc=%s", ROW(0)); else xstrfmtcat(assoc_char, "id_assoc=%s", ROW(0)); lft = atoi(ROW(1)); if (lft < smallest_lft) smallest_lft = lft; rem_assoc = xmalloc(sizeof(slurmdb_association_rec_t)); rem_assoc->id = atoi(ROW(0)); rem_assoc->cluster = xstrdup(cluster); if (addto_update_list(pg_conn->update_list, SLURMDB_REMOVE_ASSOC, rem_assoc) != SLURM_SUCCESS) error("could not add to the update list"); if (! has_jobs) { xstrfmtcat(query, "SELECT %s.remove_assoc(%s);", cluster, ROW(0)); } } END_EACH_ROW; PQclear(result); /* mark usages as deleted */ cluster_delete_assoc_usage(pg_conn, cluster, now, assoc_char); if (!has_jobs && query) { rc = DEF_QUERY_RET_RC; if (rc != SLURM_SUCCESS) { error("failed to remove account assoc"); } } if(rc == SLURM_SUCCESS) rc = pgsql_get_modified_lfts(pg_conn, cluster, smallest_lft); if (rc != SLURM_SUCCESS) { reset_pgsql_conn(pg_conn); return rc; } /* update associations to clear the limits */ query = xstrdup_printf( "UPDATE %s.%s SET mod_time=%d, deleted=1, def_qos_id=NULL, " "shares=1, max_jobs=NULL, max_nodes_pj=NULL, max_wall_pj=NULL, " "max_cpu_mins_pj=NULL WHERE (%s);", cluster, assoc_table, (int)now, assoc_char); xfree(assoc_char); rc = DEF_QUERY_RET_RC; return rc; }
extern List as_mysql_remove_qos(mysql_conn_t *mysql_conn, uint32_t uid, slurmdb_qos_cond_t *qos_cond) { ListIterator itr = NULL; List ret_list = NULL; int rc = SLURM_SUCCESS; char *object = NULL; char *extra = NULL, *query = NULL, *name_char = NULL, *assoc_char = NULL; time_t now = time(NULL); char *user_name = NULL; int set = 0; MYSQL_RES *result = NULL; MYSQL_ROW row; if (!qos_cond) { error("we need something to change"); return NULL; } if (check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; xstrcat(extra, "where deleted=0"); if (qos_cond->description_list && list_count(qos_cond->description_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_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 (qos_cond->id_list && list_count(qos_cond->id_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->id_list); while ((object = list_next(itr))) { if (!object[0]) continue; if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "id='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (qos_cond->name_list && list_count(qos_cond->name_list)) { set = 0; xstrcat(extra, " && ("); itr = list_iterator_create(qos_cond->name_list); while ((object = list_next(itr))) { if (!object[0]) continue; if (set) xstrcat(extra, " || "); xstrfmtcat(extra, "name='%s'", object); set = 1; } list_iterator_destroy(itr); xstrcat(extra, ")"); } if (!extra) { error("Nothing to remove"); return NULL; } query = xstrdup_printf("select id, name from %s %s;", qos_table, extra); xfree(extra); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); return NULL; } name_char = NULL; ret_list = list_create(slurm_destroy_char); while ((row = mysql_fetch_row(result))) { slurmdb_qos_rec_t *qos_rec = NULL; list_append(ret_list, xstrdup(row[1])); if (!name_char) xstrfmtcat(name_char, "id='%s'", row[0]); else xstrfmtcat(name_char, " || id='%s'", row[0]); if (!assoc_char) xstrfmtcat(assoc_char, "id_qos='%s'", row[0]); else xstrfmtcat(assoc_char, " || id_qos='%s'", row[0]); xstrfmtcat(extra, ", qos=replace(qos, ',%s', '')" ", delta_qos=replace(delta_qos, ',+%s', '')" ", delta_qos=replace(delta_qos, ',-%s', '')", row[0], row[0], row[0]); qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t)); /* we only need id when removing no real need to init */ qos_rec->id = slurm_atoul(row[0]); if (addto_update_list(mysql_conn->update_list, SLURMDB_REMOVE_QOS, qos_rec) != SLURM_SUCCESS) slurmdb_destroy_qos_rec(qos_rec); } mysql_free_result(result); if (!list_count(ret_list)) { errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything\n%s", query); xfree(query); return ret_list; } xfree(query); /* remove this qos from all the users/accts that have it */ query = xstrdup_printf("update %s set mod_time=%ld %s where deleted=0;", assoc_table, now, extra); xfree(extra); debug3("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); rc = mysql_db_query(mysql_conn, query); xfree(query); if (rc != SLURM_SUCCESS) { reset_mysql_conn(mysql_conn); list_destroy(ret_list); return NULL; } user_name = uid_to_string((uid_t) uid); slurm_mutex_lock(&as_mysql_cluster_list_lock); itr = list_iterator_create(as_mysql_cluster_list); while ((object = list_next(itr))) { if ((rc = remove_common(mysql_conn, DBD_REMOVE_QOS, now, user_name, qos_table, name_char, assoc_char, object, NULL, NULL)) != SLURM_SUCCESS) break; } list_iterator_destroy(itr); slurm_mutex_unlock(&as_mysql_cluster_list_lock); xfree(assoc_char); xfree(name_char); xfree(user_name); if (rc == SLURM_ERROR) { list_destroy(ret_list); return NULL; } return ret_list; }