diff --git a/NEWS b/NEWS index 677d15e993ef872b22e1afdfd9af1ee56139c176..5f1bb382d39d9932ad880ec728ef6f166f4ebbe4 100644 --- a/NEWS +++ b/NEWS @@ -45,9 +45,13 @@ documents those changes that are of interest to users and admins. later change in the partition's limits. NOTE: Not reported by "scontrol show config" to avoid changing RPCs. It will be reported in SLURM version 1.4. - -- Add support for Hostname and NodeHostname in slurm.conf being fully qualified - domain names (by Vijay Ramasubramanian, University of Maryland). For more - information see "man slurm.conf". + -- Added idea of coordinator to accounting. A coordinator can add associations + between exsisting users to the account or any sub-account they are + coordinator to. They can also add/remove other coordinators to those + accounts. + -- Add support for Hostname and NodeHostname in slurm.conf being fully + qualified domain names (by Vijay Ramasubramanian, University of Maryland). + For more information see "man slurm.conf". * Changes in SLURM 1.3.3 ======================== diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c index 64efaf6aa33fbf19b44977729db65f3d0687d21f..ac7ef16dfdea28d5d9d5d8e48a7677664f121a98 100644 --- a/src/common/assoc_mgr.c +++ b/src/common/assoc_mgr.c @@ -443,7 +443,7 @@ extern int assoc_mgr_is_user_acct_coord(void *db_conn, } list_iterator_destroy(itr); - if(!found_user) { + if(!found_user || !found_user->coord_accts) { slurm_mutex_unlock(&local_user_lock); return 0; } @@ -625,6 +625,7 @@ extern int assoc_mgr_update_local_users(acct_update_object_t *update) { acct_user_rec_t * rec = NULL; acct_user_rec_t * object = NULL; + ListIterator itr = NULL; int rc = SLURM_SUCCESS; struct passwd *passwd_ptr = NULL; @@ -681,6 +682,23 @@ extern int assoc_mgr_update_local_users(acct_update_object_t *update) } list_delete_item(itr); break; + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: + if(!rec) { + //rc = SLURM_ERROR; + break; + } + /* We always get a complete list here */ + if(!object->coord_accts) { + if(rec->coord_accts) + list_flush(rec->coord_accts); + } else { + if(rec->coord_accts) + list_destroy(rec->coord_accts); + rec->coord_accts = object->coord_accts; + object->coord_accts = NULL; + } + break; default: break; } diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c index 41583384067cf067db53047536c7276f5ecdb087..f7f545d37766e50fd5c94350f3f9a14e423d1ddd 100644 --- a/src/common/slurm_accounting_storage.c +++ b/src/common/slurm_accounting_storage.c @@ -64,7 +64,7 @@ typedef struct slurm_acct_storage_ops { int (*add_users) (void *db_conn, uint32_t uid, List user_list); int (*add_coord) (void *db_conn, uint32_t uid, - char *acct, + List acct_list, acct_user_cond_t *user_q); int (*add_accts) (void *db_conn, uint32_t uid, List acct_list); @@ -87,7 +87,7 @@ typedef struct slurm_acct_storage_ops { List (*remove_users) (void *db_conn, uint32_t uid, acct_user_cond_t *user_q); List (*remove_coord) (void *db_conn, uint32_t uid, - char *acct, + List acct_list, acct_user_cond_t *user_q); List (*remove_accts) (void *db_conn, uint32_t uid, acct_account_cond_t *acct_q); @@ -585,7 +585,9 @@ extern int unpack_acct_user_rec(void **object, Buf buffer) object_ptr->assoc_list = list_create(destroy_acct_association_rec); for(i=0; i<count; i++) { - unpack_acct_association_rec((void *)&assoc, buffer); + if(unpack_acct_association_rec((void *)&assoc, buffer) + == SLURM_ERROR) + goto unpack_error; list_append(object_ptr->assoc_list, assoc); } } @@ -593,7 +595,9 @@ extern int unpack_acct_user_rec(void **object, Buf buffer) if(count) { object_ptr->coord_accts = list_create(destroy_acct_coord_rec); for(i=0; i<count; i++) { - unpack_acct_coord_rec((void *)&coord, buffer); + if(unpack_acct_coord_rec((void *)&coord, buffer) + == SLURM_ERROR) + goto unpack_error; list_append(object_ptr->coord_accts, coord); } } @@ -698,7 +702,9 @@ extern int unpack_acct_account_rec(void **object, Buf buffer) object_ptr->assoc_list = list_create(destroy_acct_association_rec); for(i=0; i<count; i++) { - unpack_acct_association_rec((void *)&assoc, buffer); + if(unpack_acct_association_rec((void *)&assoc, buffer) + == SLURM_ERROR) + goto unpack_error; list_append(object_ptr->assoc_list, assoc); } } @@ -745,6 +751,7 @@ extern int unpack_acct_coord_rec(void **object, Buf buffer) *object = object_ptr; safe_unpackstr_xmalloc(&object_ptr->acct_name, &uint32_tmp, buffer); safe_unpack16(&object_ptr->sub_acct, buffer); + return SLURM_SUCCESS; unpack_error: destroy_acct_coord_rec(object_ptr); @@ -990,7 +997,9 @@ extern int unpack_acct_association_rec(void **object, Buf buffer) object_ptr->accounting_list = list_create(destroy_acct_accounting_rec); for(i=0; i<count; i++) { - unpack_acct_accounting_rec((void **)&acct_info, buffer); + if(unpack_acct_accounting_rec((void **)&acct_info, + buffer) == SLURM_ERROR) + goto unpack_error; list_append(object_ptr->accounting_list, acct_info); } } @@ -1704,6 +1713,8 @@ extern void pack_acct_update_object(acct_update_object_t *object, Buf buffer) case ACCT_MODIFY_USER: case ACCT_ADD_USER: case ACCT_REMOVE_USER: + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: my_function = pack_acct_user_rec; break; case ACCT_ADD_ASSOC: @@ -1746,6 +1757,8 @@ extern int unpack_acct_update_object(acct_update_object_t **object, Buf buffer) case ACCT_MODIFY_USER: case ACCT_ADD_USER: case ACCT_REMOVE_USER: + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: my_function = unpack_acct_user_rec; my_destroy = destroy_acct_user_rec; break; @@ -1981,12 +1994,12 @@ extern int acct_storage_g_add_users(void *db_conn, uint32_t uid, } extern int acct_storage_g_add_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { if (slurm_acct_storage_init(NULL) < 0) return SLURM_ERROR; return (*(g_acct_storage_context->ops.add_coord)) - (db_conn, uid, acct, user_q); + (db_conn, uid, acct_list, user_q); } extern int acct_storage_g_add_accounts(void *db_conn, uint32_t uid, @@ -2066,12 +2079,13 @@ extern List acct_storage_g_remove_users(void *db_conn, uint32_t uid, } extern List acct_storage_g_remove_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { if (slurm_acct_storage_init(NULL) < 0) return NULL; return (*(g_acct_storage_context->ops.remove_coord)) - (db_conn, uid, acct, user_q); + (db_conn, uid, acct_list, user_q); } extern List acct_storage_g_remove_accounts(void *db_conn, uint32_t uid, diff --git a/src/common/slurm_accounting_storage.h b/src/common/slurm_accounting_storage.h index 37b766a5b401ef801b50d56c3024b9d280a9a957..d3c204d81c8b2fdcc7798383e7ad8af09ba2b9e7 100644 --- a/src/common/slurm_accounting_storage.h +++ b/src/common/slurm_accounting_storage.h @@ -65,10 +65,12 @@ typedef enum { ACCT_UPDATE_NOTSET, ACCT_ADD_USER, ACCT_ADD_ASSOC, + ACCT_ADD_COORD, ACCT_MODIFY_USER, ACCT_MODIFY_ASSOC, ACCT_REMOVE_USER, - ACCT_REMOVE_ASSOC + ACCT_REMOVE_ASSOC, + ACCT_REMOVE_COORD } acct_update_type_t; /* Association conditions used for queries of the database */ @@ -333,12 +335,12 @@ extern int acct_storage_g_add_users(void *db_conn, uint32_t uid, /* * add users as account coordinators - * IN: acct name of account + * IN: acct_list list of char *'s of names of accounts * IN: acct_user_cond_t *user_q * RET: SLURM_SUCCESS on success SLURM_ERROR else */ extern int acct_storage_g_add_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q); + List acct_list, acct_user_cond_t *user_q); /* @@ -369,82 +371,83 @@ extern int acct_storage_g_add_associations(void *db_conn, uint32_t uid, * modify existing users in the accounting system * IN: acct_user_cond_t *user_q * IN: acct_user_rec_t *user - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_modify_users(void *db_conn, uint32_t uid, - acct_user_cond_t *user_q, - acct_user_rec_t *user); + acct_user_cond_t *user_q, + acct_user_rec_t *user); /* * modify existing accounts in the accounting system * IN: acct_acct_cond_t *acct_q * IN: acct_account_rec_t *acct - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_modify_accounts(void *db_conn, uint32_t uid, - acct_account_cond_t *acct_q, - acct_account_rec_t *acct); + acct_account_cond_t *acct_q, + acct_account_rec_t *acct); /* * modify existing clusters in the accounting system * IN: acct_cluster_cond_t *cluster_q * IN: acct_cluster_rec_t *cluster - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_modify_clusters(void *db_conn, uint32_t uid, - acct_cluster_cond_t *cluster_q, - acct_cluster_rec_t *cluster); + acct_cluster_cond_t *cluster_q, + acct_cluster_rec_t *cluster); /* * modify existing associations in the accounting system * IN: acct_association_cond_t *assoc_q * IN: acct_association_rec_t *assoc - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_modify_associations(void *db_conn, uint32_t uid, - acct_association_cond_t *assoc_q, - acct_association_rec_t *assoc); + acct_association_cond_t *assoc_q, + acct_association_rec_t *assoc); /* * remove users from accounting system * IN: acct_user_cond_t *user_q - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_remove_users(void *db_conn, uint32_t uid, - acct_user_cond_t *user_q); + acct_user_cond_t *user_q); /* * remove users from being a coordinator of an account - * IN: acct name of acct + * IN: acct_list list of char *'s of names of accounts * IN: acct_user_cond_t *user_q - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_remove_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q); + List acct_list, + acct_user_cond_t *user_q); /* * remove accounts from accounting system * IN: acct_account_cond_t *acct_q - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_remove_accounts(void *db_conn, uint32_t uid, - acct_account_cond_t *acct_q); + acct_account_cond_t *acct_q); /* * remove clusters from accounting system * IN: acct_cluster_cond_t *cluster_q - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_remove_clusters(void *db_conn, uint32_t uid, - acct_cluster_cond_t *cluster_q); + acct_cluster_cond_t *cluster_q); /* * remove associations from accounting system * IN: acct_association_cond_t *assoc_q - * RET: SLURM_SUCCESS on success SLURM_ERROR else + * RET: List containing (char *'s) else NULL on error */ extern List acct_storage_g_remove_associations(void *db_conn, uint32_t uid, - acct_association_cond_t *assoc_q); + acct_association_cond_t *assoc_q); /* * get info from the storage diff --git a/src/common/slurmdbd_defs.c b/src/common/slurmdbd_defs.c index 2ad430c79ecd925ac097a4a297101c2ab002c394..3de583ca23c9410b8ad7fb39ca1ab568541956dd 100644 --- a/src/common/slurmdbd_defs.c +++ b/src/common/slurmdbd_defs.c @@ -1210,7 +1210,10 @@ static int _purge_job_start_req(void) void inline slurmdbd_free_acct_coord_msg(dbd_acct_coord_msg_t *msg) { if(msg) { - xfree(msg->acct); + if(msg->acct_list) { + list_destroy(msg->acct_list); + msg->acct_list = NULL; + } destroy_acct_user_cond(msg->cond); xfree(msg); } @@ -1437,7 +1440,23 @@ void inline slurmdbd_free_usage_msg(slurmdbd_msg_type_t type, void inline slurmdbd_pack_acct_coord_msg(dbd_acct_coord_msg_t *msg, Buf buffer) { - packstr(msg->acct, buffer); + char *acct = NULL; + ListIterator itr = NULL; + uint32_t count = 0; + + if(msg->acct_list) + count = list_count(msg->acct_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(msg->acct_list); + while((acct = list_next(itr))) { + packstr(acct, buffer); + } + list_iterator_destroy(itr); + } + count = 0; + pack_acct_user_cond(msg->cond, buffer); } @@ -1445,12 +1464,25 @@ int inline slurmdbd_unpack_acct_coord_msg(dbd_acct_coord_msg_t **msg, Buf buffer) { uint32_t uint32_tmp; + int i; + char *acct = NULL; + uint32_t count = 0; dbd_acct_coord_msg_t *msg_ptr = xmalloc(sizeof(dbd_acct_coord_msg_t)); *msg = msg_ptr; - safe_unpackstr_xmalloc(&msg_ptr->acct, &uint32_tmp, buffer); + safe_unpack32(&count, buffer); + if(count) { + msg_ptr->acct_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&acct, &uint32_tmp, buffer); + list_append(msg_ptr->acct_list, acct); + } + } + if(unpack_acct_user_cond((void *)&msg_ptr->cond, buffer) == SLURM_ERROR) goto unpack_error; + return SLURM_SUCCESS; + unpack_error: slurmdbd_free_acct_coord_msg(msg_ptr); *msg = NULL; diff --git a/src/common/slurmdbd_defs.h b/src/common/slurmdbd_defs.h index 9a97af1e14a45f193d9acd625205c3e30fde1f74..c75cd084295bb7c5a8170cd9a73439f730032628 100644 --- a/src/common/slurmdbd_defs.h +++ b/src/common/slurmdbd_defs.h @@ -121,7 +121,7 @@ typedef struct slurmdbd_msg { } slurmdbd_msg_t; typedef struct { - char *acct; + List acct_list; /* list of account names (char *'s) */ acct_user_cond_t *cond; } dbd_acct_coord_msg_t; diff --git a/src/database/mysql_common.c b/src/database/mysql_common.c index 24e4de9ec8f25acfe37af0d77a0fc244c023d290..35847b0a2130590ff60fbcf7707fe80bb4102722 100644 --- a/src/database/mysql_common.c +++ b/src/database/mysql_common.c @@ -146,12 +146,22 @@ static int _mysql_make_table_current(MYSQL *mysql_db, char *table_name, } } if(!found) { - info("adding column %s after %s", fields[i].name, - fields[i-1].name); - xstrfmtcat(query, " add %s %s after %s,", - fields[i].name, - fields[i].options, - fields[i-1].name); + if(i) { + info("adding column %s after %s", + fields[i].name, + fields[i-1].name); + xstrfmtcat(query, " add %s %s after %s,", + fields[i].name, + fields[i].options, + fields[i-1].name); + } else { + info("adding column %s at the beginning", + fields[i].name, + fields[i-1].name); + xstrfmtcat(query, " add %s %s first,", + fields[i].name, + fields[i].options); + } } i++; diff --git a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c index 3fea73d5a053a18af289ebb2377ec6fe0bed6068..a2a5d5177ad9b5ffd8bb32df5ea4414e7f0c64df 100644 --- a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c +++ b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c @@ -251,7 +251,7 @@ extern int acct_storage_p_add_users(void *db_conn, uint32_t uid, } extern int acct_storage_p_add_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { return SLURM_SUCCESS; } @@ -309,7 +309,8 @@ extern List acct_storage_p_remove_users(void *db_conn, uint32_t uid, } extern List acct_storage_p_remove_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index 49757b6c72737a14e5fc75091eae5cfb2fb9d043..2e3ea135692df0275443b2b5a5e9ff97c94c1880 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -181,6 +181,8 @@ static int _addto_update_list(List update_list, acct_update_type_t type, case ACCT_MODIFY_USER: case ACCT_ADD_USER: case ACCT_REMOVE_USER: + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: update_object->objects = list_create(destroy_acct_user_rec); break; case ACCT_ADD_ASSOC: @@ -405,6 +407,7 @@ static int _modify_common(mysql_conn_t *mysql_conn, return SLURM_SUCCESS; } + static int _modify_unset_users(mysql_conn_t *mysql_conn, acct_association_rec_t *assoc, char *acct, @@ -600,6 +603,9 @@ static int _remove_common(mysql_conn_t *mysql_conn, return SLURM_ERROR; } + + if(table == acct_coord_table) + return SLURM_SUCCESS; /* mark deleted=1 or remove completely the accounting tables @@ -794,6 +800,86 @@ static int _remove_common(mysql_conn_t *mysql_conn, return rc; } +static int _get_user_coords(mysql_conn_t *mysql_conn, acct_user_rec_t *user) +{ + char *query = NULL; + acct_coord_rec_t *coord = NULL; + MYSQL_RES *result = NULL; + MYSQL_ROW row; + ListIterator itr = NULL; + + if(!user) { + error("We need a user to fill in."); + return SLURM_ERROR; + } + + if(!user->coord_accts) + user->coord_accts = list_create(destroy_acct_coord_rec); + + query = xstrdup_printf( + "select acct from %s where user='%s' && deleted=0", + acct_coord_table, user->name); + + if(!(result = + mysql_db_query_ret(mysql_conn->acct_mysql_db, query, 0))) { + xfree(query); + return SLURM_ERROR; + } + xfree(query); + while((row = mysql_fetch_row(result))) { + coord = xmalloc(sizeof(acct_coord_rec_t)); + list_append(user->coord_accts, coord); + coord->acct_name = xstrdup(row[0]); + coord->sub_acct = 0; + if(query) + xstrcat(query, " || "); + else + query = xstrdup_printf( + "select distinct t1.acct from " + "%s as t1, %s as t2 where ", + assoc_table, assoc_table); + /* Make sure we don't get the same + * account back since we want to keep + * track of the sub-accounts. + */ + xstrfmtcat(query, "(t2.acct='%s' " + "&& t1.lft between t2.lft " + "and t2.rgt && t1.user='' " + "&& t1.acct!='%s')", + coord->acct_name, coord->acct_name); + } + mysql_free_result(result); + + if(query) { + if(!(result = mysql_db_query_ret( + mysql_conn->acct_mysql_db, query, 0))) { + xfree(query); + return SLURM_ERROR; + } + xfree(query); + + itr = list_iterator_create(user->coord_accts); + while((row = mysql_fetch_row(result))) { + + while((coord = list_next(itr))) { + if(!strcmp(coord->acct_name, row[0])) + break; + } + list_iterator_reset(itr); + if(coord) + continue; + + coord = xmalloc(sizeof(acct_coord_rec_t)); + list_append(user->coord_accts, coord); + coord->acct_name = xstrdup(row[0]); + coord->sub_acct = 1; + } + list_iterator_destroy(itr); + mysql_free_result(result); + } + return SLURM_SUCCESS; +} + static int _get_db_index(MYSQL *acct_mysql_db, time_t submit, uint32_t jobid, uint32_t associd) { @@ -840,6 +926,8 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db) { int rc = SLURM_SUCCESS; storage_field_t acct_coord_table_fields[] = { + { "creation_time", "int unsigned not null" }, + { "mod_time", "int unsigned default 0 not null" }, { "deleted", "tinyint default 0" }, { "acct", "tinytext not null" }, { "user", "tinytext not null" }, @@ -1370,6 +1458,8 @@ extern int acct_storage_p_commit(mysql_conn_t *mysql_conn, bool commit) case ACCT_MODIFY_USER: case ACCT_ADD_USER: case ACCT_REMOVE_USER: + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: rc = assoc_mgr_update_local_users(object); break; case ACCT_ADD_ASSOC: @@ -1521,9 +1611,91 @@ extern int acct_storage_p_add_users(mysql_conn_t *mysql_conn, uint32_t uid, } extern int acct_storage_p_add_coord(mysql_conn_t *mysql_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { #ifdef HAVE_MYSQL + char *query = NULL, *user = NULL, *acct = NULL; + char *user_name = NULL, *txn_query = NULL; + struct passwd *pw = NULL; + ListIterator itr, itr2; + time_t now = time(NULL); + int rc = SLURM_SUCCESS; + acct_user_rec_t *user_rec = NULL; + + if(!user_q || !user_q->user_list || !list_count(user_q->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 SLURM_ERROR; + + if((pw=getpwuid(uid))) { + user_name = pw->pw_name; + } + + itr = list_iterator_create(user_q->user_list); + itr2 = list_iterator_create(acct_list); + while((user = list_next(itr))) { + while((acct = list_next(itr2))) { + if(query) + xstrfmtcat(query, ", (%d, %d, '%s', '%s')", + now, now, acct, user); + else + query = xstrdup_printf( + "insert into %s (creation_time, " + "mod_time, acct, user) values " + "(%d, %d, '%s', '%s')", + acct_coord_table, + now, now, acct, user); + + if(txn_query) + xstrfmtcat(txn_query, + ", (%d, %u, '%s', '%s', '%s')", + now, DBD_ADD_ACCOUNT_COORDS, user, + user_name, acct); + else + xstrfmtcat(txn_query, + "insert into %s " + "(timestamp, action, name, " + "actor, info) " + "values (%d, %u, '%s', '%s', '%s')", + txn_table, + now, DBD_ADD_ACCOUNT_COORDS, user, + user_name, acct); + } + list_iterator_reset(itr2); + } + list_iterator_destroy(itr); + list_iterator_destroy(itr2); + + + if(query) { + xstrfmtcat(query, + " on duplicate key update mod_time=%d, deleted=0;%s", + now, txn_query); + debug3("%d query\n%s", mysql_conn->conn, query); + rc = mysql_db_query(mysql_conn->acct_mysql_db, 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_q->user_list); + while((user = list_next(itr))) { + user_rec = xmalloc(sizeof(acct_user_rec_t)); + user_rec->name = xstrdup(user); + _get_user_coords(mysql_conn, user_rec); + _addto_update_list(mysql_conn->update_list, + ACCT_ADD_COORD, user_rec); + } + list_iterator_destroy(itr); + } + return SLURM_SUCCESS; #else return SLURM_ERROR; @@ -2296,7 +2468,6 @@ extern List acct_storage_p_modify_users(mysql_conn_t *mysql_conn, uint32_t uid, xfree(query); return NULL; } - xfree(query); rc = 0; ret_list = list_create(slurm_destroy_char); @@ -2313,10 +2484,13 @@ extern List acct_storage_p_modify_users(mysql_conn_t *mysql_conn, uint32_t uid, mysql_free_result(result); if(!list_count(ret_list)) { - debug3("didn't effect anything"); + 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, ")"); if(_modify_common(mysql_conn, DBD_MODIFY_USERS, now, @@ -2433,7 +2607,6 @@ extern List acct_storage_p_modify_accts(mysql_conn_t *mysql_conn, uint32_t uid, xfree(vals); return NULL; } - xfree(query); rc = 0; ret_list = list_create(slurm_destroy_char); @@ -2451,10 +2624,13 @@ extern List acct_storage_p_modify_accts(mysql_conn_t *mysql_conn, uint32_t uid, mysql_free_result(result); if(!list_count(ret_list)) { - debug3("didn't effect anything"); + errno = SLURM_NO_CHANGE_IN_DATA; + debug3("didn't effect anything\n%s", query); + xfree(query); xfree(vals); return ret_list; } + xfree(query); xstrcat(name_char, ")"); if(_modify_common(mysql_conn, DBD_MODIFY_ACCOUNTS, now, @@ -2548,7 +2724,6 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn, error("no result given for %s", extra); return NULL; } - xfree(query); rc = 0; ret_list = list_create(slurm_destroy_char); @@ -2565,10 +2740,13 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn, mysql_free_result(result); if(!list_count(ret_list)) { - debug3("didn't effect anything"); + errno = SLURM_NO_CHANGE_IN_DATA; + debug3("didn't effect anything\n%s", query); xfree(vals); + xfree(query); return ret_list; } + xfree(query); if(vals) { send_char = xstrdup_printf("(%s)", name_char); @@ -2607,10 +2785,12 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL; time_t now = time(NULL); struct passwd *pw = NULL; - char *user = NULL; - int set = 0, i = 0; + char *user_name = NULL; + int set = 0, i = 0, is_admin=0; MYSQL_RES *result = NULL; MYSQL_ROW row; + acct_user_rec_t user; + char *massoc_req_inx[] = { "id", "acct", @@ -2642,8 +2822,47 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, if(_check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; + memset(&user, 0, sizeof(acct_user_rec_t)); + user.uid = uid; + + /* This only works when running though the slurmdbd. + * THERE IS NO AUTHENTICATION WHEN RUNNNING OUT OF THE + * SLURMDBD! + */ + if(slurmdbd_conf) { + /* we have to check the authentication here in the + * plugin since we don't know what accounts are being + * referenced until after the query. Here we will + * set if they are an operator or greater and then + * check it below after the query. + */ + if(uid == slurmdbd_conf->slurm_user_id + || assoc_mgr_get_admin_level(mysql_conn, uid) + >= ACCT_ADMIN_OPERATOR) + is_admin = 1; + else { + if(assoc_mgr_fill_in_user(mysql_conn, &user, 1) + != SLURM_SUCCESS) { + error("couldn't get information for this user"); + errno = SLURM_ERROR; + return NULL; + } + if(!user.coord_accts || !list_count(user.coord_accts)) { + error("This user doesn't have any " + "coordinator abilities"); + errno = ESLURM_ACCESS_DENIED; + return NULL; + } + } + } else { + /* Setting this here just makes it easier down below + * since user will not be filled in. + */ + is_admin = 1; + } + if((pw=getpwuid(uid))) { - user = pw->pw_name; + user_name = pw->pw_name; } if(assoc_q->acct_list && list_count(assoc_q->acct_list)) { @@ -2771,6 +2990,33 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, int account_type=0; /* MYSQL_RES *result2 = NULL; */ /* MYSQL_ROW row2; */ + + if(!is_admin) { + acct_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; + mysql_free_result(result); + xfree(vals); + list_destroy(ret_list); + return NULL; + } + itr = list_iterator_create(user.coord_accts); + while((coord = list_next(itr))) { + if(!strcasecmp(coord->acct_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]); + continue; + } + } + if(row[MASSOC_PART][0]) { // see if there is a partition name object = xstrdup_printf( @@ -2866,6 +3112,7 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, if(!list_count(ret_list)) { + errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything"); xfree(vals); return ret_list; @@ -2874,7 +3121,7 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn, if(vals) { if(_modify_common(mysql_conn, DBD_MODIFY_ASSOCS, now, - user, assoc_table, name_char, vals) + user_name, assoc_table, name_char, vals) == SLURM_ERROR) { error("Couldn't modify associations"); list_destroy(ret_list); @@ -2972,7 +3219,6 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, xfree(query); return NULL; } - xfree(query); rc = 0; ret_list = list_create(slurm_destroy_char); @@ -2991,10 +3237,13 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, mysql_free_result(result); if(!list_count(ret_list)) { - debug3("didn't effect anything"); + errno = SLURM_NO_CHANGE_IN_DATA; + debug3("didn't effect anything\n%s", query); + xfree(query); return ret_list; } - + xfree(query); + if(_remove_common(mysql_conn, DBD_REMOVE_USERS, now, user_name, user_table, name_char, assoc_char) == SLURM_ERROR) { @@ -3004,8 +3253,20 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, return NULL; } xfree(name_char); + + query = xstrdup_printf( + "update %s as t2, set deleted=1, mod_time=%d where %s", + acct_coord_table, now, assoc_char); xfree(assoc_char); + rc = mysql_db_query(mysql_conn->acct_mysql_db, query); + xfree(query); + if(rc != SLURM_SUCCESS) { + error("Couldn't remove user coordinators"); + list_destroy(ret_list); + return NULL; + } + return ret_list; #else @@ -3014,10 +3275,176 @@ extern List acct_storage_p_remove_users(mysql_conn_t *mysql_conn, uint32_t uid, } extern List acct_storage_p_remove_coord(mysql_conn_t *mysql_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { #ifdef HAVE_MYSQL - return NULL; + char *query = NULL, *object = NULL, *extra = NULL, *last_user = NULL; + char *user_name = NULL; + struct passwd *pw = NULL; + time_t now = time(NULL); + int set = 0, is_admin=0; + ListIterator itr = NULL; + acct_user_rec_t *user_rec = NULL; + List ret_list = NULL; + List user_list = NULL; + MYSQL_RES *result = NULL; + MYSQL_ROW row; + acct_user_rec_t user; + + if(_check_connection(mysql_conn) != SLURM_SUCCESS) + return NULL; + + memset(&user, 0, sizeof(acct_user_rec_t)); + user.uid = uid; + + /* This only works when running though the slurmdbd. + * THERE IS NO AUTHENTICATION WHEN RUNNNING OUT OF THE + * SLURMDBD! + */ + if(slurmdbd_conf) { + /* we have to check the authentication here in the + * plugin since we don't know what accounts are being + * referenced until after the query. Here we will + * set if they are an operator or greater and then + * check it below after the query. + */ + if(uid == slurmdbd_conf->slurm_user_id + || assoc_mgr_get_admin_level(mysql_conn, uid) + >= ACCT_ADMIN_OPERATOR) + is_admin = 1; + else { + if(assoc_mgr_fill_in_user(mysql_conn, &user, 1) + != SLURM_SUCCESS) { + error("couldn't get information for this user"); + errno = SLURM_ERROR; + return NULL; + } + if(!user.coord_accts || !list_count(user.coord_accts)) { + error("This user doesn't have any " + "coordinator abilities"); + errno = ESLURM_ACCESS_DENIED; + return NULL; + } + } + } else { + /* Setting this here just makes it easier down below + * since user will not be filled in. + */ + is_admin = 1; + } + + if((pw=getpwuid(uid))) { + user_name = pw->pw_name; + } + + if(user_q->user_list && list_count(user_q->user_list)) { + set = 0; + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " ("); + + itr = list_iterator_create(user_q->user_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "user='%s'", 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(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "acct='%s'", object); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + query = xstrdup_printf( + "select user, acct from %s where deleted=0 && %s order by user", + acct_coord_table, extra); + + debug3("%d query\n%s", mysql_conn->conn, query); + if(!(result = + mysql_db_query_ret(mysql_conn->acct_mysql_db, query, 0))) { + xfree(query); + xfree(extra); + 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) { + acct_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->acct_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]); + continue; + } + } + 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); + + if(_remove_common(mysql_conn, DBD_REMOVE_ACCOUNT_COORDS, now, + user_name, acct_coord_table, extra, NULL) + == SLURM_ERROR) { + list_destroy(ret_list); + list_destroy(user_list); + xfree(extra); + return NULL; + } + xfree(extra); + /* get the update list set */ + itr = list_iterator_create(user_list); + while((last_user = list_next(itr))) { + user_rec = xmalloc(sizeof(acct_user_rec_t)); + user_rec->name = xstrdup(last_user); + _get_user_coords(mysql_conn, user_rec); + _addto_update_list(mysql_conn->update_list, + ACCT_REMOVE_COORD, user_rec); + } + list_iterator_destroy(itr); + list_destroy(user_list); + + return ret_list; #else return NULL; #endif @@ -3111,7 +3538,6 @@ extern List acct_storage_p_remove_accts(mysql_conn_t *mysql_conn, uint32_t uid, xfree(query); return NULL; } - xfree(query); rc = 0; ret_list = list_create(slurm_destroy_char); @@ -3130,9 +3556,12 @@ extern List acct_storage_p_remove_accts(mysql_conn_t *mysql_conn, uint32_t uid, mysql_free_result(result); if(!list_count(ret_list)) { - debug3("didn't effect anything"); + errno = SLURM_NO_CHANGE_IN_DATA; + debug3("didn't effect anything\n%s", query); + xfree(query); return ret_list; } + xfree(query); if(_remove_common(mysql_conn, DBD_REMOVE_ACCOUNTS, now, user_name, acct_table, name_char, assoc_char) @@ -3227,6 +3656,7 @@ extern List acct_storage_p_remove_clusters(mysql_conn_t *mysql_conn, 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; @@ -3296,9 +3726,10 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, time_t now = time(NULL); struct passwd *pw = NULL; char *user_name = NULL; - int set = 0, i = 0; + int set = 0, i = 0, is_admin=0; MYSQL_RES *result = NULL; MYSQL_ROW row; + acct_user_rec_t user; /* if this changes you will need to edit the corresponding * enum below also t1 is step_table */ @@ -3329,6 +3760,45 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, if(_check_connection(mysql_conn) != SLURM_SUCCESS) return NULL; + memset(&user, 0, sizeof(acct_user_rec_t)); + user.uid = uid; + + /* This only works when running though the slurmdbd. + * THERE IS NO AUTHENTICATION WHEN RUNNNING OUT OF THE + * SLURMDBD! + */ + if(slurmdbd_conf) { + /* we have to check the authentication here in the + * plugin since we don't know what accounts are being + * referenced until after the query. Here we will + * set if they are an operator or greater and then + * check it below after the query. + */ + if(uid == slurmdbd_conf->slurm_user_id + || assoc_mgr_get_admin_level(mysql_conn, uid) + >= ACCT_ADMIN_OPERATOR) + is_admin = 1; + else { + if(assoc_mgr_fill_in_user(mysql_conn, &user, 1) + != SLURM_SUCCESS) { + error("couldn't get information for this user"); + errno = SLURM_ERROR; + return NULL; + } + if(!user.coord_accts || !list_count(user.coord_accts)) { + error("This user doesn't have any " + "coordinator abilities"); + errno = ESLURM_ACCESS_DENIED; + return NULL; + } + } + } else { + /* Setting this here just makes it easier down below + * since user will not be filled in. + */ + is_admin = 1; + } + xstrcat(extra, "where id>0 && deleted=0"); if((pw=getpwuid(uid))) { @@ -3411,7 +3881,6 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, xfree(query); return NULL; } - xfree(query); rc = 0; while((row = mysql_fetch_row(result))) { @@ -3427,6 +3896,7 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, mysql_free_result(result); if(!name_char) { + errno = SLURM_NO_CHANGE_IN_DATA; debug3("didn't effect anything\n%s", query); xfree(query); return ret_list; @@ -3451,7 +3921,29 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, ret_list = list_create(slurm_destroy_char); while((row = mysql_fetch_row(result))) { acct_association_rec_t *rem_assoc = NULL; + if(!is_admin) { + acct_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; + goto end_it; + } + itr = list_iterator_create(user.coord_accts); + while((coord = list_next(itr))) { + if(!strcasecmp(coord->acct_name, + row[RASSOC_ACCT])) + 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[RASSOC_ACCT]); + continue; + } + } if(row[RASSOC_PART][0]) { // see if there is a partition name object = xstrdup_printf( @@ -3505,6 +3997,14 @@ extern List acct_storage_p_remove_associations(mysql_conn_t *mysql_conn, xfree(assoc_char); return ret_list; +end_it: + if(ret_list) { + list_destroy(ret_list); + ret_list = NULL; + } + mysql_free_result(result); + + return NULL; #else return NULL; #endif @@ -3522,8 +4022,8 @@ extern List acct_storage_p_get_users(mysql_conn_t *mysql_conn, char *object = NULL; int set = 0; int i=0; - MYSQL_RES *result = NULL, *coord_result = NULL; - MYSQL_ROW row, coord_row; + MYSQL_RES *result = NULL; + MYSQL_ROW row; /* if this changes you will need to edit the corresponding enum */ char *user_req_inx[] = { @@ -3643,77 +4143,7 @@ empty: /* else */ /* user->uid = (uint32_t)NO_VAL; */ if(user_q && user_q->with_coords) { - user->coord_accts = list_create(destroy_acct_coord_rec); - query = xstrdup_printf( - "select acct from %s where user='%s' " - "&& deleted=0", - acct_coord_table, user->name); - - if(!(coord_result = - mysql_db_query_ret(mysql_conn->acct_mysql_db, - query, 0))) { - xfree(query); - continue; - } - xfree(query); - while((coord_row = mysql_fetch_row(coord_result))) { - acct_coord_rec_t *coord = - xmalloc(sizeof(acct_coord_rec_t)); - list_append(user->coord_accts, coord); - coord->acct_name = xstrdup(coord_row[0]); - coord->sub_acct = 0; - if(query) - xstrcat(query, " || "); - else - query = xstrdup_printf( - "select distinct t1.acct from " - "%s as t1, %s as t2 where ", - assoc_table, assoc_table); - /* Add 1 to the lft to not include the - * one we are looking at. Distinct - * above to only get 1 instance since the acct - * will most likely be on multiple clusters. - */ - xstrfmtcat(query, "(t2.acct='%s' " - "&& t1.lft between t2.lft+1 " - "and t2.rgt && t1.user='')", - coord->acct_name); - } - mysql_free_result(coord_result); - - if(query) { - if(!(coord_result = mysql_db_query_ret( - mysql_conn->acct_mysql_db, - query, 0))) { - xfree(query); - continue; - } - xfree(query); - - itr = list_iterator_create(user->coord_accts); - while((coord_row = - mysql_fetch_row(coord_result))) { - acct_coord_rec_t *coord = NULL; - - while((coord = list_next(itr))) { - if(!strcmp(coord->acct_name, - coord_row[0])) - break; - } - list_iterator_reset(itr); - if(coord) - continue; - - coord = xmalloc( - sizeof(acct_coord_rec_t)); - list_append(user->coord_accts, coord); - coord->acct_name = - xstrdup(coord_row[0]); - coord->sub_acct = 1; - } - list_iterator_destroy(itr); - mysql_free_result(coord_result); - } + _get_user_coords(mysql_conn, user); } if(user_q && user_q->with_assocs) { diff --git a/src/plugins/accounting_storage/none/accounting_storage_none.c b/src/plugins/accounting_storage/none/accounting_storage_none.c index 61cea5b3e70a01ab87ba52735f46bc414ed99c3e..26a4c554d700cd548302bc18370be1d977fa21d2 100644 --- a/src/plugins/accounting_storage/none/accounting_storage_none.c +++ b/src/plugins/accounting_storage/none/accounting_storage_none.c @@ -109,7 +109,7 @@ extern int acct_storage_p_add_users(void *db_conn, uint32_t uid, } extern int acct_storage_p_add_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { return SLURM_SUCCESS; } @@ -167,7 +167,8 @@ extern List acct_storage_p_remove_users(void *db_conn, uint32_t uid, } extern List acct_storage_p_remove_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c index 2c66748879cb5f681a81ff51e9b449485a37c3ac..b4a59425612e2399d99ba856702ca6749804b47c 100644 --- a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c +++ b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c @@ -763,7 +763,7 @@ extern int acct_storage_p_add_users(PGconn *acct_pgsql_db, uint32_t uid, } extern int acct_storage_p_add_coord(PGconn *acct_pgsql_db, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { return SLURM_SUCCESS; } @@ -822,7 +822,8 @@ extern List acct_storage_p_remove_users(PGconn *acct_pgsql_db, uint32_t uid, } extern List acct_storage_p_remove_coord(PGconn *acct_pgsql_db, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { return SLURM_SUCCESS; } diff --git a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c index b05297cfc4bc34f222dc51d28b0749478259fdb9..cbfba517fce818563e7e7f3beac6b7b935697690 100644 --- a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c +++ b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c @@ -183,13 +183,13 @@ extern int acct_storage_p_add_users(void *db_conn, uint32_t uid, List user_list) } extern int acct_storage_p_add_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, acct_user_cond_t *user_q) { slurmdbd_msg_t req; dbd_acct_coord_msg_t get_msg; int rc, resp_code; - get_msg.acct = acct; + get_msg.acct_list = acct_list; get_msg.cond = user_q; req.msg_type = DBD_ADD_ACCOUNT_COORDS; @@ -277,7 +277,15 @@ extern List acct_storage_p_modify_users(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_MODIFY_USERS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -309,7 +317,15 @@ extern List acct_storage_p_modify_accts(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_MODIFY_ACCOUNTS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -343,7 +359,15 @@ extern List acct_storage_p_modify_clusters(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_MODIFY_CLUSTERS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -377,7 +401,15 @@ extern List acct_storage_p_modify_associations(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_MODIFY_ASSOCS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -409,7 +441,15 @@ extern List acct_storage_p_remove_users(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_REMOVE_USERS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -423,7 +463,8 @@ extern List acct_storage_p_remove_users(void *db_conn, uint32_t uid, } extern List acct_storage_p_remove_coord(void *db_conn, uint32_t uid, - char *acct, acct_user_cond_t *user_q) + List acct_list, + acct_user_cond_t *user_q) { slurmdbd_msg_t req; dbd_acct_coord_msg_t get_msg; @@ -433,7 +474,7 @@ extern List acct_storage_p_remove_coord(void *db_conn, uint32_t uid, List ret_list = NULL; - get_msg.acct = acct; + get_msg.acct_list = acct_list; get_msg.cond = user_q; req.msg_type = DBD_REMOVE_ACCOUNT_COORDS; @@ -442,7 +483,15 @@ extern List acct_storage_p_remove_coord(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_REMOVE_ACCOUNT_COORDS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -474,7 +523,15 @@ extern List acct_storage_p_remove_accts(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_REMOVE_ACCTS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -506,7 +563,15 @@ extern List acct_storage_p_remove_clusters(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_REMOVE_CLUSTERS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { @@ -538,7 +603,15 @@ extern List acct_storage_p_remove_associations(void *db_conn, uint32_t uid, if (rc != SLURM_SUCCESS) error("slurmdbd: DBD_REMOVE_ASSOCS failure: %m"); - else if (resp.msg_type != DBD_GOT_LIST) { + else if (resp.msg_type == DBD_RC) { + dbd_rc_msg_t *msg = resp.data; + if(msg->return_code == SLURM_SUCCESS) { + info("%s", msg->comment); + ret_list = list_create(NULL); + } else + error("%s", msg->comment); + slurmdbd_free_rc_msg(msg); + } else if (resp.msg_type != DBD_GOT_LIST) { error("slurmdbd: response type not DBD_GOT_LIST: %u", resp.msg_type); } else { diff --git a/src/plugins/select/bluegene/block_allocator/block_allocator.c b/src/plugins/select/bluegene/block_allocator/block_allocator.c index 8605c86b1c2215d70c3191ed36e5df4ec3df6f1f..3b9a9247685848d73d7c2673681c1e70eb5d7bfd 100644 --- a/src/plugins/select/bluegene/block_allocator/block_allocator.c +++ b/src/plugins/select/bluegene/block_allocator/block_allocator.c @@ -1501,8 +1501,10 @@ extern int reset_ba_system(bool track_down_nodes) */ extern int removable_set_bps(char *bps) { +#ifdef HAVE_BG int j=0, number; - int x,y,z; + int x; + int y,z; int start[BA_SYSTEM_DIMENSIONS]; int end[BA_SYSTEM_DIMENSIONS]; @@ -1531,15 +1533,10 @@ extern int removable_set_bps(char *bps) for (x = start[X]; x <= end[X]; x++) { for (y = start[Y]; y <= end[Y]; y++) { for (z = start[Z]; z <= end[Z]; z++) { - if(!ba_system_ptr->grid[x] -#ifdef HAVE_BG - [y][z] -#endif + if(!ba_system_ptr->grid[x][y][z] .used) - ba_system_ptr->grid[x] -#ifdef HAVE_BG - [y][z] -#endif + ba_system_ptr-> + grid[x][y][z] .used = 2; } } @@ -1558,16 +1555,8 @@ extern int removable_set_bps(char *bps) / HOSTLIST_BASE; z = (number % HOSTLIST_BASE); j+=3; - if(!ba_system_ptr->grid[x] -#ifdef HAVE_BG - [y][z] -#endif - .used) - ba_system_ptr->grid[x] -#ifdef HAVE_BG - [y][z] -#endif - .used = 2; + if(!ba_system_ptr->grid[x][y][z].used) + ba_system_ptr->grid[x][y][z].used = 2; if(bps[j] != ',') break; @@ -1575,13 +1564,16 @@ extern int removable_set_bps(char *bps) } j++; } - +#endif return SLURM_SUCCESS; } extern int reset_all_removed_bps() { int x; +#ifdef HAVE_BG + int y,z; +#endif for (x = 0; x < DIM_SIZE[X]; x++) { #ifdef HAVE_BG diff --git a/src/sacctmgr/sacctmgr.c b/src/sacctmgr/sacctmgr.c index 12d5ab5a273adc1dbac4fa68b75e7ff7fe646792..b19eebb2fb04b10441706ea2ecc73d8864a2917d 100644 --- a/src/sacctmgr/sacctmgr.c +++ b/src/sacctmgr/sacctmgr.c @@ -463,15 +463,17 @@ static void _add_it (int argc, char *argv[]) /* First identify the entity to add */ if (strncasecmp (argv[0], "User", 1) == 0) { error_code = sacctmgr_add_user((argc - 1), &argv[1]); + } else if (strncasecmp (argv[0], "Cluster", 2) == 0) { + error_code = sacctmgr_add_cluster((argc - 1), &argv[1]); + } else if (strncasecmp (argv[0], "Coordinator", 2) == 0) { + error_code = sacctmgr_add_coord((argc - 1), &argv[1]); } else if (strncasecmp (argv[0], "Account", 1) == 0) { error_code = sacctmgr_add_account((argc - 1), &argv[1]); - } else if (strncasecmp (argv[0], "Cluster", 1) == 0) { - error_code = sacctmgr_add_cluster((argc - 1), &argv[1]); } else { exit_code = 1; fprintf(stderr, "No valid entity in add command\n"); fprintf(stderr, "Input line must include, "); - fprintf(stderr, "\"User\", \"Account\", "); + fprintf(stderr, "\"User\", \"Account\", \"Coordinator\", "); fprintf(stderr, "or \"Cluster\"\n"); } @@ -555,13 +557,15 @@ static void _delete_it (int argc, char *argv[]) error_code = sacctmgr_delete_user((argc - 1), &argv[1]); } else if (strncasecmp (argv[0], "Account", 1) == 0) { error_code = sacctmgr_delete_account((argc - 1), &argv[1]); - } else if (strncasecmp (argv[0], "Cluster", 1) == 0) { + } else if (strncasecmp (argv[0], "Cluster", 2) == 0) { error_code = sacctmgr_delete_cluster((argc - 1), &argv[1]); + } else if (strncasecmp (argv[0], "Coordinator", 2) == 0) { + error_code = sacctmgr_delete_coord((argc - 1), &argv[1]); } else { exit_code = 1; fprintf(stderr, "No valid entity in delete command\n"); fprintf(stderr, "Input line must include "); - fprintf(stderr, "\"User\", \"Account\", "); + fprintf(stderr, "\"User\", \"Account\", \"Coordinator\", "); fprintf(stderr, "or \"Cluster\"\n"); } diff --git a/src/sacctmgr/sacctmgr.h b/src/sacctmgr/sacctmgr.h index 7796bb7241ce87fb3c9906e1d7a73375e9236d50..df5f380b0de20975d75462ee3b74100a3e449e0c 100644 --- a/src/sacctmgr/sacctmgr.h +++ b/src/sacctmgr/sacctmgr.h @@ -101,6 +101,7 @@ extern int sacctmgr_add_association(int argc, char *argv[]); extern int sacctmgr_add_user(int argc, char *argv[]); extern int sacctmgr_add_account(int argc, char *argv[]); extern int sacctmgr_add_cluster(int argc, char *argv[]); +extern int sacctmgr_add_coord(int argc, char *argv[]); extern int sacctmgr_list_association(int argc, char *argv[]); extern int sacctmgr_list_user(int argc, char *argv[]); @@ -116,6 +117,7 @@ extern int sacctmgr_delete_association(int argc, char *argv[]); extern int sacctmgr_delete_user(int argc, char *argv[]); extern int sacctmgr_delete_account(int argc, char *argv[]); extern int sacctmgr_delete_cluster(int argc, char *argv[]); +extern int sacctmgr_delete_coord(int argc, char *argv[]); /* common.c */ extern int parse_option_end(char *option); diff --git a/src/sacctmgr/user_functions.c b/src/sacctmgr/user_functions.c index dfc4883ce184175b0d24d09088c0f960a7c995a6..1daa8de10fea64184b6e9e6df9853df26b7a675e 100644 --- a/src/sacctmgr/user_functions.c +++ b/src/sacctmgr/user_functions.c @@ -135,24 +135,34 @@ static int _set_rec(int *start, int argc, char *argv[], user->default_acct = strip_quotes(argv[i]+end, NULL); u_set = 1; } else if (strncasecmp (argv[i], "FairShare", 1) == 0) { + if(!association) + continue; if (get_uint(argv[i]+end, &association->fairshare, "FairShare") == SLURM_SUCCESS) a_set = 1; } else if (strncasecmp (argv[i], "MaxCPUSec", 4) == 0) { + if(!association) + continue; if (get_uint(argv[i]+end, &association->max_cpu_secs_per_job, "MaxCPUSec") == SLURM_SUCCESS) a_set = 1; } else if (strncasecmp (argv[i], "MaxJobs", 4) == 0) { + if(!association) + continue; if (get_uint(argv[i]+end, &association->max_jobs, "MaxJobs") == SLURM_SUCCESS) a_set = 1; } else if (strncasecmp (argv[i], "MaxNodes", 4) == 0) { + if(!association) + continue; if (get_uint(argv[i]+end, &association->max_nodes_per_job, "MaxNodes") == SLURM_SUCCESS) a_set = 1; } else if (strncasecmp (argv[i], "MaxWall", 4) == 0) { + if(!association) + continue; mins = time_str2mins(argv[i]+end); if (mins != NO_VAL) { association->max_wall_duration_per_job @@ -671,6 +681,93 @@ end_it: return rc; } +extern int sacctmgr_add_coord(int argc, char *argv[]) +{ + int rc = SLURM_SUCCESS; + int i=0; + int cond_set = 0; + acct_user_cond_t *user_cond = xmalloc(sizeof(acct_user_cond_t)); + char *name = NULL; + char *user_str = NULL; + char *acct_str = NULL; + ListIterator itr = NULL; + + user_cond->user_list = list_create(slurm_destroy_char); + user_cond->def_acct_list = list_create(slurm_destroy_char); + + user_cond->assoc_cond = xmalloc(sizeof(acct_association_cond_t)); + user_cond->assoc_cond->user_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->acct_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->cluster_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->partition_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->fairshare = NO_VAL; + user_cond->assoc_cond->max_cpu_secs_per_job = NO_VAL; + user_cond->assoc_cond->max_jobs = NO_VAL; + user_cond->assoc_cond->max_nodes_per_job = NO_VAL; + user_cond->assoc_cond->max_wall_duration_per_job = NO_VAL; + + for (i=0; i<argc; i++) { + cond_set = _set_cond(&i, argc, argv, user_cond, NULL); + } + + if(!cond_set) { + printf(" You need to specify a user list " + "and account list here.\n"); + destroy_acct_user_cond(user_cond); + return SLURM_ERROR; + } + + itr = list_iterator_create(user_cond->user_list); + while((name = list_next(itr))) { + xstrfmtcat(user_str, " %s\n", name); + + } + list_iterator_destroy(itr); + + if(!user_str) { + printf(" You need to specify a user list " + "and account list here.\n"); + destroy_acct_user_cond(user_cond); + return SLURM_ERROR; + } + itr = list_iterator_create(user_cond->assoc_cond->acct_list); + while((name = list_next(itr))) { + xstrfmtcat(acct_str, " %s\n", name); + + } + list_iterator_destroy(itr); + if(!acct_str) { + printf(" You need to specify a user list " + "and account list here.\n"); + destroy_acct_user_cond(user_cond); + return SLURM_ERROR; + } + + printf(" Adding Coordinator User(s)\n%s", user_str); + printf(" To Account(s) and all sub-accounts\n%s", acct_str); + + notice_thread_init(); + rc = acct_storage_g_add_coord(db_conn, my_uid, + user_cond->assoc_cond->acct_list, + user_cond); + notice_thread_fini(); + destroy_acct_user_cond(user_cond); + + if(rc == SLURM_SUCCESS) { + if(commit_check("Would you like to commit changes?")) { + acct_storage_g_commit(db_conn, 1); + } else { + printf(" Changes Discarded\n"); + acct_storage_g_commit(db_conn, 0); + } + } else { + printf(" error: Problem adding coordinator\n"); + rc = SLURM_ERROR; + } + + return rc; +} + extern int sacctmgr_list_user(int argc, char *argv[]) { int rc = SLURM_SUCCESS; @@ -1222,3 +1319,110 @@ extern int sacctmgr_delete_user(int argc, char *argv[]) return rc; } + +extern int sacctmgr_delete_coord(int argc, char *argv[]) +{ + int rc = SLURM_SUCCESS; + int i=0, set=0; + int cond_set = 0; + acct_user_cond_t *user_cond = xmalloc(sizeof(acct_user_cond_t)); + char *name = NULL; + char *user_str = NULL; + char *acct_str = NULL; + ListIterator itr = NULL; + List ret_list = NULL; + + user_cond->user_list = list_create(slurm_destroy_char); + user_cond->def_acct_list = list_create(slurm_destroy_char); + + user_cond->assoc_cond = xmalloc(sizeof(acct_association_cond_t)); + user_cond->assoc_cond->user_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->acct_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->cluster_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->partition_list = list_create(slurm_destroy_char); + user_cond->assoc_cond->fairshare = NO_VAL; + user_cond->assoc_cond->max_cpu_secs_per_job = NO_VAL; + user_cond->assoc_cond->max_jobs = NO_VAL; + user_cond->assoc_cond->max_nodes_per_job = NO_VAL; + user_cond->assoc_cond->max_wall_duration_per_job = NO_VAL; + + for (i=0; i<argc; i++) { + cond_set = _set_cond(&i, argc, argv, user_cond, NULL); + } + + if(!cond_set) { + printf(" You need to specify a user list " + "or account list here.\n"); + destroy_acct_user_cond(user_cond); + return SLURM_ERROR; + } + + itr = list_iterator_create(user_cond->user_list); + while((name = list_next(itr))) { + xstrfmtcat(user_str, " %s\n", name); + + } + list_iterator_destroy(itr); + + itr = list_iterator_create(user_cond->assoc_cond->acct_list); + while((name = list_next(itr))) { + xstrfmtcat(acct_str, " %s\n", name); + + } + list_iterator_destroy(itr); + if(!user_str && !acct_str) { + printf(" You need to specify a user list " + "or an account list here.\n"); + destroy_acct_user_cond(user_cond); + return SLURM_ERROR; + } + /* FIX ME: This list should be recieved from the slurmdbd not + * just assumed. Right now it doesn't do it correctly though. + * This is why we are doing it this way. + */ + if(user_str) { + printf(" Removing Coordinators with user name\n%s", user_str); + if(acct_str) + printf(" From Account(s)\n%s", acct_str); + else + printf(" From all accounts\n"); + } else + printf(" Removing all users from Accounts\n%s", acct_str); + + notice_thread_init(); + ret_list = acct_storage_g_remove_coord(db_conn, my_uid, + user_cond->assoc_cond->acct_list, + user_cond); + destroy_acct_user_cond(user_cond); + + + if(ret_list && list_count(ret_list)) { + char *object = NULL; + ListIterator itr = list_iterator_create(ret_list); + printf(" Removed Coordinators (sub accounts not listed)...\n"); + while((object = list_next(itr))) { + printf(" %s\n", object); + } + list_iterator_destroy(itr); + set = 1; + } else if(ret_list) { + printf(" Nothing removed\n"); + } else { + printf(" Error with request\n"); + rc = SLURM_ERROR; + } + + if(ret_list) + list_destroy(ret_list); + notice_thread_fini(); + if(set) { + if(commit_check("Would you like to commit changes?")) + acct_storage_g_commit(db_conn, 1); + else { + printf(" Changes Discarded\n"); + acct_storage_g_commit(db_conn, 0); + } + } + + return rc; +} diff --git a/src/slurmctld/proc_req.c b/src/slurmctld/proc_req.c index 8219bb4c51d0fa7d74296a3709d8c603eb6da08d..ed3d9d2f8c679f485ee1f570a96d135e883ab54e 100644 --- a/src/slurmctld/proc_req.c +++ b/src/slurmctld/proc_req.c @@ -2854,6 +2854,8 @@ inline static void _slurm_rpc_accounting_update_msg(slurm_msg_t *msg) case ACCT_MODIFY_USER: case ACCT_ADD_USER: case ACCT_REMOVE_USER: + case ACCT_ADD_COORD: + case ACCT_REMOVE_COORD: rc = assoc_mgr_update_local_users(object); break; case ACCT_ADD_ASSOC: diff --git a/src/slurmdbd/proc_req.c b/src/slurmdbd/proc_req.c index 7c55e662e8209586bd2c81d69d0ab4efbe10661e..6f63b1ece476b1f39659eb251dc80dd99efe3cf1 100644 --- a/src/slurmdbd/proc_req.c +++ b/src/slurmdbd/proc_req.c @@ -304,7 +304,7 @@ static int _add_accounts(void *db_conn, memset(&user, 0, sizeof(acct_user_rec_t)); user.uid = *uid; - if(!assoc_mgr_fill_in_user(db_conn, &user, 1)) { + if(assoc_mgr_fill_in_user(db_conn, &user, 1) != SLURM_SUCCESS) { comment = "Your user has not been added to the accounting system yet."; error("%s", comment); rc = SLURM_ERROR; @@ -356,12 +356,15 @@ static int _add_account_coords(void *db_conn, if(*uid != slurmdbd_conf->slurm_user_id && assoc_mgr_get_admin_level(db_conn, *uid) < ACCT_ADMIN_OPERATOR) { ListIterator itr = NULL; + ListIterator itr2 = NULL; acct_user_rec_t user; acct_coord_rec_t *coord = NULL; - + char *acct = NULL; + int bad = 0; + memset(&user, 0, sizeof(acct_user_rec_t)); user.uid = *uid; - if(!assoc_mgr_fill_in_user(db_conn, &user, 1)) { + if(assoc_mgr_fill_in_user(db_conn, &user, 1) != SLURM_SUCCESS) { comment = "Your user has not been added to the accounting system yet."; error("%s", comment); rc = SLURM_ERROR; @@ -373,14 +376,23 @@ static int _add_account_coords(void *db_conn, rc = ESLURM_ACCESS_DENIED; goto end_it; } - itr = list_iterator_create(user.coord_accts); - while((coord = list_next(itr))) { - if(!strcasecmp(coord->acct_name, get_msg->acct)) + itr = list_iterator_create(get_msg->acct_list); + itr2 = list_iterator_create(user.coord_accts); + while((acct = list_next(itr))) { + while((coord = list_next(itr2))) { + if(!strcasecmp(coord->acct_name, acct)) + break; + } + if(!coord) { + bad = 1; break; + } + list_iterator_reset(itr2); } + list_iterator_destroy(itr2); list_iterator_destroy(itr); - if(!coord) { + if(bad) { comment = "Your user doesn't have privilege to preform this action"; error("%s", comment); rc = ESLURM_ACCESS_DENIED; @@ -388,7 +400,7 @@ static int _add_account_coords(void *db_conn, } } - rc = acct_storage_g_add_coord(db_conn, *uid, get_msg->acct, + rc = acct_storage_g_add_coord(db_conn, *uid, get_msg->acct_list, get_msg->cond); end_it: slurmdbd_free_acct_coord_msg(get_msg); @@ -423,7 +435,7 @@ static int _add_assocs(void *db_conn, memset(&user, 0, sizeof(acct_user_rec_t)); user.uid = *uid; - if(!assoc_mgr_fill_in_user(db_conn, &user, 1)) { + if(assoc_mgr_fill_in_user(db_conn, &user, 1) != SLURM_SUCCESS) { comment = "Your user has not been added to the accounting system yet."; error("%s", comment); rc = SLURM_ERROR; @@ -514,7 +526,7 @@ static int _add_users(void *db_conn, memset(&user, 0, sizeof(acct_user_rec_t)); user.uid = *uid; - if(!assoc_mgr_fill_in_user(db_conn, &user, 1)) { + if(assoc_mgr_fill_in_user(db_conn, &user, 1) != SLURM_SUCCESS) { comment = "Your user has not been added to the accounting system yet."; error("%s", comment); rc = SLURM_ERROR; @@ -1116,8 +1128,26 @@ static int _modify_accounts(void *db_conn, } - list_msg.my_list = acct_storage_g_modify_accounts( - db_conn, *uid, get_msg->cond, get_msg->rec); + if(!(list_msg.my_list = acct_storage_g_modify_accounts( + db_conn, *uid, get_msg->cond, get_msg->rec))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_modify_msg(DBD_MODIFY_ACCOUNTS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_MODIFY_ACCOUNTS); + return rc; + } slurmdbd_free_modify_msg(DBD_MODIFY_ACCOUNTS, get_msg); *out_buffer = init_buf(1024); @@ -1139,16 +1169,6 @@ static int _modify_assocs(void *db_conn, debug2("DBD_MODIFY_ASSOCS: called"); - if(*uid != slurmdbd_conf->slurm_user_id - && assoc_mgr_get_admin_level(db_conn, *uid) < ACCT_ADMIN_OPERATOR) { - comment = "Your user doesn't have privilege to preform this action"; - error("%s", comment); - *out_buffer = make_dbd_rc_msg(ESLURM_ACCESS_DENIED, - comment, DBD_MODIFY_ASSOCS); - - return ESLURM_ACCESS_DENIED; - } - if (slurmdbd_unpack_modify_msg(DBD_MODIFY_ASSOCS, &get_msg, in_buffer) != SLURM_SUCCESS) { comment = "Failed to unpack DBD_MODIFY_ASSOCS message"; @@ -1159,8 +1179,31 @@ static int _modify_assocs(void *db_conn, } - list_msg.my_list = acct_storage_g_modify_associations(db_conn, *uid, - get_msg->cond, get_msg->rec); + /* All authentication needs to be done inside the plugin since we are + * unable to know what accounts this request is talking about + * until we process it through the database. + */ + + if(!(list_msg.my_list = acct_storage_g_modify_associations( + db_conn, *uid, get_msg->cond, get_msg->rec))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_modify_msg(DBD_MODIFY_ASSOCS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_MODIFY_ASSOCS); + return rc; + } slurmdbd_free_modify_msg(DBD_MODIFY_ASSOCS, get_msg); *out_buffer = init_buf(1024); @@ -1202,8 +1245,26 @@ static int _modify_clusters(void *db_conn, debug2("DBD_MODIFY_CLUSTERS: called"); - list_msg.my_list = acct_storage_g_modify_clusters(db_conn, *uid, - get_msg->cond, get_msg->rec); + if(!(list_msg.my_list = acct_storage_g_modify_clusters( + db_conn, *uid, get_msg->cond, get_msg->rec))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_modify_msg(DBD_MODIFY_CLUSTERS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_MODIFY_CLUSTERS); + return rc; + } slurmdbd_free_modify_msg(DBD_MODIFY_CLUSTERS, get_msg); *out_buffer = init_buf(1024); @@ -1253,11 +1314,29 @@ static int _modify_users(void *db_conn, ACCT_ADMIN_NOTSET; } - list_msg.my_list = acct_storage_g_modify_users( - db_conn, *uid, get_msg->cond, get_msg->rec); + if(!(list_msg.my_list = acct_storage_g_modify_users( + db_conn, *uid, get_msg->cond, get_msg->rec))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_modify_msg(DBD_MODIFY_USERS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_MODIFY_USERS); + return rc; + } slurmdbd_free_modify_msg(DBD_MODIFY_USERS, get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list) @@ -1443,18 +1522,29 @@ static int _remove_accounts(void *db_conn, return SLURM_ERROR; } - list_msg.my_list = acct_storage_g_remove_accounts( - db_conn, *uid, get_msg->cond); -/* this should be done inside the plugin */ -/* if(rc == SLURM_SUCCESS) { */ -/* memset(&assoc_q, 0, sizeof(acct_association_cond_t)); */ -/* assoc_q.acct_list = */ -/* ((acct_account_cond_t *)get_msg->cond)->acct_list; */ -/* list_msg.my_list = acct_storage_g_remove_associations(db_conn, *uid, &assoc_q); */ -/* } */ + if(!(list_msg.my_list = acct_storage_g_remove_accounts( + db_conn, *uid, get_msg->cond))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_cond_msg(DBD_REMOVE_ACCOUNTS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_REMOVE_ACCOUNTS); + return rc; + } slurmdbd_free_cond_msg(DBD_REMOVE_ACCOUNTS, get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list) @@ -1474,37 +1564,54 @@ static int _remove_account_coords(void *db_conn, debug2("DBD_REMOVE_ACCOUNT_COORDS: called"); - if(*uid != slurmdbd_conf->slurm_user_id - && assoc_mgr_get_admin_level(db_conn, *uid) < ACCT_ADMIN_OPERATOR) { - comment = "Your user doesn't have privilege to preform this action"; - error("%s", comment); - *out_buffer = make_dbd_rc_msg( - ESLURM_ACCESS_DENIED, comment, - DBD_REMOVE_ACCOUNT_COORDS); - - return ESLURM_ACCESS_DENIED; - } - if (slurmdbd_unpack_acct_coord_msg(&get_msg, in_buffer) != SLURM_SUCCESS) { comment = "Failed to unpack DBD_REMOVE_ACCOUNT_COORDS message"; error("%s", comment); - *out_buffer = make_dbd_rc_msg( - SLURM_ERROR, comment, DBD_REMOVE_ACCOUNT_COORDS); - return SLURM_ERROR; + rc = SLURM_ERROR; + goto end_it; } - list_msg.my_list = acct_storage_g_remove_coord( - db_conn, *uid, get_msg->acct, get_msg->cond); + /* All authentication needs to be done inside the plugin since we are + * unable to know what accounts this request is talking about + * until we process it through the database. + */ + + if(!(list_msg.my_list = acct_storage_g_remove_coord( + db_conn, *uid, get_msg->acct_list, get_msg->cond))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_acct_coord_msg(get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, + DBD_REMOVE_ACCOUNT_COORDS); + return rc; + } slurmdbd_free_acct_coord_msg(get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list) list_destroy(list_msg.my_list); return rc; +end_it: + slurmdbd_free_acct_coord_msg(get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_ADD_ACCOUNT_COORDS); + return rc; + } static int _remove_assocs(void *db_conn, @@ -1516,17 +1623,6 @@ static int _remove_assocs(void *db_conn, char *comment = NULL; debug2("DBD_REMOVE_ASSOCS: called"); - - if(*uid != slurmdbd_conf->slurm_user_id - && assoc_mgr_get_admin_level(db_conn, *uid) < ACCT_ADMIN_OPERATOR) { - comment = "Your user doesn't have privilege to preform this action"; - error("%s", comment); - *out_buffer = make_dbd_rc_msg(ESLURM_ACCESS_DENIED, - comment, DBD_REMOVE_ASSOCS); - - return ESLURM_ACCESS_DENIED; - } - if (slurmdbd_unpack_cond_msg(DBD_REMOVE_ASSOCS, &get_msg, in_buffer) != SLURM_SUCCESS) { comment = "Failed to unpack DBD_REMOVE_ASSOCS message"; @@ -1535,12 +1631,35 @@ static int _remove_assocs(void *db_conn, comment, DBD_REMOVE_ASSOCS); return SLURM_ERROR; } - - list_msg.my_list = acct_storage_g_remove_associations( - db_conn, *uid, get_msg->cond); + /* All authentication needs to be done inside the plugin since we are + * unable to know what accounts this request is talking about + * until we process it through the database. + */ + + if(!(list_msg.my_list = acct_storage_g_remove_associations( + db_conn, *uid, get_msg->cond))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_cond_msg(DBD_REMOVE_ASSOCS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_REMOVE_ASSOCS); + return rc; + } + slurmdbd_free_cond_msg(DBD_REMOVE_ASSOCS, get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list) @@ -1580,18 +1699,29 @@ static int _remove_clusters(void *db_conn, return SLURM_ERROR; } - list_msg.my_list = acct_storage_g_remove_clusters( - db_conn, *uid, get_msg->cond); -/* this should be done inside the plugin */ -/* if(rc == SLURM_SUCCESS) { */ -/* memset(&assoc_q, 0, sizeof(acct_association_cond_t)); */ -/* assoc_q.cluster_list = */ -/* ((acct_cluster_cond_t *)get_msg->cond)->cluster_list; */ -/* list_msg.my_list = acct_storage_g_remove_associations(db_conn, *uid, &assoc_q); */ -/* } */ + if(!(list_msg.my_list = acct_storage_g_remove_clusters( + db_conn, *uid, get_msg->cond))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_cond_msg(DBD_REMOVE_CLUSTERS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_REMOVE_CLUSTERS); + return rc; + } slurmdbd_free_cond_msg(DBD_REMOVE_CLUSTERS, get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list) @@ -1629,18 +1759,29 @@ static int _remove_users(void *db_conn, return SLURM_ERROR; } - list_msg.my_list = acct_storage_g_remove_users( - db_conn, *uid, get_msg->cond); -/* this should be done inside the plugin */ - /* if(rc == SLURM_SUCCESS) { */ -/* memset(&assoc_q, 0, sizeof(acct_association_cond_t)); */ -/* assoc_q.user_list = */ -/* ((acct_user_cond_t *)get_msg->cond)->user_list; */ -/* list_msg.my_list = acct_storage_g_remove_associations(db_conn, *uid, &assoc_q); */ -/* } */ + if(!(list_msg.my_list = acct_storage_g_remove_users( + db_conn, *uid, get_msg->cond))) { + if(errno == ESLURM_ACCESS_DENIED) { + comment = "Your user doesn't have privilege to preform this action"; + rc = ESLURM_ACCESS_DENIED; + } else if(errno == SLURM_ERROR) { + comment = "Something was wrong with your query"; + rc = SLURM_ERROR; + } else if(errno == SLURM_NO_CHANGE_IN_DATA) { + comment = "Request didn't affect anything"; + rc = SLURM_SUCCESS; + } else { + comment = "Unkown issue"; + rc = SLURM_ERROR; + } + error("%s", comment); + slurmdbd_free_cond_msg(DBD_REMOVE_USERS, get_msg); + *out_buffer = make_dbd_rc_msg(rc, comment, DBD_REMOVE_USERS); + return rc; + } slurmdbd_free_cond_msg(DBD_REMOVE_USERS, get_msg); - *out_buffer = init_buf(1024); + *out_buffer = init_buf(1024); pack16((uint16_t) DBD_GOT_LIST, *out_buffer); slurmdbd_pack_list_msg(DBD_GOT_LIST, &list_msg, *out_buffer); if(list_msg.my_list)