From 28e0984daf1fad3625731fdf23121c1d29a452cf Mon Sep 17 00:00:00 2001 From: Danny Auble <da@llnl.gov> Date: Wed, 2 Sep 2009 22:52:11 +0000 Subject: [PATCH] added logic to make it possible for qos to be updated on the fly and added to associations when they are added to the mix --- src/common/assoc_mgr.c | 17 ++ src/common/slurm_accounting_storage.c | 4 +- .../mysql/accounting_storage_mysql.c | 137 ++++++++++++++--- testsuite/expect/globals_accounting | 1 + testsuite/expect/test21.26 | 145 ++++++++---------- 5 files changed, 192 insertions(+), 112 deletions(-) diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c index 3679399e150..95b367abaac 100644 --- a/src/common/assoc_mgr.c +++ b/src/common/assoc_mgr.c @@ -178,6 +178,10 @@ static int _local_update_assoc_qos_list(acct_association_rec_t *assoc, return SLURM_SUCCESS; } + /* Even though we only use the valid_qos bitstr for things we + need to keep the list around for now since we don't pack the + bitstr for state save. + */ new_qos_itr = list_iterator_create(new_qos_list); curr_qos_itr = list_iterator_create(assoc->qos_list); @@ -1699,6 +1703,19 @@ extern int assoc_mgr_update_assocs(acct_update_object_t *update) rec->qos_list = object->qos_list; object->qos_list = NULL; } + + if(rec->user && (g_qos_count > 0)) { + if(!rec->valid_qos + || (bit_size(rec->valid_qos) + != g_qos_count)) { + FREE_NULL_BITMAP( + rec->valid_qos); + rec->valid_qos = + bit_alloc(g_qos_count); + } + set_qos_bitstr_from_list( + rec->valid_qos, rec->qos_list); + } } if(!slurmdbd_conf && !parents_changed) { diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c index 969f1b6e754..a44be40fe69 100644 --- a/src/common/slurm_accounting_storage.c +++ b/src/common/slurm_accounting_storage.c @@ -7585,8 +7585,8 @@ extern void log_assoc_rec(acct_association_rec_t *assoc_ptr, List qos_list) if(assoc_ptr->user) debug2(" User : %s(%u)", assoc_ptr->user, assoc_ptr->uid); - debug2(" UsedJobs : %u", assoc_ptr->used_jobs); - debug2(" RawUsage : %Lf", assoc_ptr->usage_raw); + debug2(" UsedJobs : %u", assoc_ptr->used_jobs); + debug2(" RawUsage : %Lf", assoc_ptr->usage_raw); } /* diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index 4d031082310..b2cdecee040 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -688,6 +688,9 @@ static int _setup_association_limits(acct_association_rec_t *assoc, xstrcat(*cols, ", qos"); xstrfmtcat(*vals, ", '%s'", default_qos_str); xstrfmtcat(*extra, ", qos=\"%s\"", default_qos_str); + if(!assoc->qos_list) + assoc->qos_list = list_create(slurm_destroy_char); + slurm_addto_char_list(assoc->qos_list, default_qos_str); } else { /* clear the qos */ xstrcat(*cols, ", qos, delta_qos"); @@ -1560,6 +1563,108 @@ static int _set_assoc_lft_rgt( return rc; } +static int _set_assoc_limits_for_add( + mysql_conn_t *mysql_conn, acct_association_rec_t *assoc) +{ + MYSQL_RES *result = NULL; + MYSQL_ROW row; + char *query = NULL; + char *parent = NULL; + char *qos_delta = NULL; + + enum { + ASSOC_REQ_PARENT_ID, + ASSOC_REQ_MJ, + ASSOC_REQ_MSJ, + ASSOC_REQ_MCPJ, + ASSOC_REQ_MNPJ, + ASSOC_REQ_MWPJ, + ASSOC_REQ_MCMPJ, + ASSOC_REQ_QOS, + ASSOC_REQ_DELTA_QOS, + }; + + xassert(assoc); + + if(assoc->parent_acct) + parent = assoc->parent_acct; + else if(assoc->user) + parent = assoc->acct; + else + return SLURM_SUCCESS; + + query = xstrdup_printf("call get_parent_limits(\"%s\", " + "\"%s\", \"%s\", %u);" + "select @par_id, @mj, @msj, @mcpj, " + "@mnpj, @mwpj, @mcmpj, @qos, @delta_qos;", + assoc_table, parent, assoc->cluster, 0); + debug4("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query); + if(!(result = mysql_db_query_ret(mysql_conn->db_conn, query, 1))) { + xfree(query); + return SLURM_ERROR; + } + xfree(query); + + if(!(row = mysql_fetch_row(result))) + goto end_it; + + if(row[ASSOC_REQ_MJ] && assoc->max_jobs == NO_VAL) + assoc->max_jobs = atoi(row[ASSOC_REQ_MJ]); + if(row[ASSOC_REQ_MSJ] && assoc->max_submit_jobs == NO_VAL) + assoc->max_submit_jobs = atoi(row[ASSOC_REQ_MSJ]); + if(row[ASSOC_REQ_MCPJ] && assoc->max_cpus_pj == NO_VAL) + assoc->max_cpus_pj = atoi(row[ASSOC_REQ_MCPJ]); + if(row[ASSOC_REQ_MNPJ] && assoc->max_nodes_pj == NO_VAL) + assoc->max_nodes_pj = atoi(row[ASSOC_REQ_MNPJ]); + if(row[ASSOC_REQ_MWPJ] && assoc->max_wall_pj == NO_VAL) + assoc->max_wall_pj = atoi(row[ASSOC_REQ_MWPJ]); + if(row[ASSOC_REQ_MCMPJ] && assoc->max_cpu_mins_pj == NO_VAL) + assoc->max_cpu_mins_pj = atoi(row[ASSOC_REQ_MCMPJ]); + + if(assoc->qos_list) { + int set = 0; + char *tmp_char = NULL; + ListIterator qos_itr = list_iterator_create(assoc->qos_list); + while((tmp_char = list_next(qos_itr))) { + /* we don't want to include blank names */ + if(!tmp_char[0]) + continue; + + if(!set) { + if(tmp_char[0] != '+' && tmp_char[0] != '-') + break; + set = 1; + } + xstrfmtcat(qos_delta, ",%s", tmp_char); + } + list_iterator_destroy(qos_itr); + + if(tmp_char) { + /* we have the qos here nothing from parents + needed */ + goto end_it; + } + list_flush(assoc->qos_list); + } else + assoc->qos_list = list_create(slurm_destroy_char); + + if(row[ASSOC_REQ_QOS][0]) + slurm_addto_char_list(assoc->qos_list, row[ASSOC_REQ_QOS]+1); + + if(row[ASSOC_REQ_DELTA_QOS][0]) + slurm_addto_char_list(assoc->qos_list, + row[ASSOC_REQ_DELTA_QOS]+1); + if(qos_delta) { + slurm_addto_char_list(assoc->qos_list, qos_delta+1); + xfree(qos_delta); + } + +end_it: + mysql_free_result(result); + + return SLURM_SUCCESS; +} + /* This function will take the object given and free it later so it * needed to be removed from a list if in one before */ @@ -4435,8 +4540,7 @@ extern int acct_storage_p_add_associations(mysql_conn_t *mysql_conn, * the assoc_id will already be set */ if(!assoc_id) { - affect_rows = _last_affected_rows( - mysql_conn->db_conn); + affect_rows = _last_affected_rows(mysql_conn->db_conn); assoc_id = mysql_insert_id(mysql_conn->db_conn); //info("last id was %d", assoc_id); } @@ -4461,29 +4565,12 @@ extern int acct_storage_p_add_associations(mysql_conn_t *mysql_conn, } } object->parent_id = my_par_id; - - if(!moved_parent && !object->lft) - _set_assoc_lft_rgt(mysql_conn, object); - - - /* get the parent id only if we haven't moved the - * parent since we get the total list if that has - * happened */ - if(!moved_parent && - (!last_parent || !last_cluster - || strcmp(parent, last_parent) - || strcmp(object->cluster, last_cluster))) { - uint32_t tmp32 = 0; - if((tmp32 = _get_parent_id(mysql_conn, - parent, - object->cluster))) { - my_par_id = tmp32; - - last_parent = parent; - last_cluster = object->cluster; - } - } - object->parent_id = my_par_id; + + if(!moved_parent) { + _set_assoc_limits_for_add(mysql_conn, object); + if(!object->lft) + _set_assoc_lft_rgt(mysql_conn, object); + } if(_addto_update_list(mysql_conn->update_list, ACCT_ADD_ASSOC, object) == SLURM_SUCCESS) { diff --git a/testsuite/expect/globals_accounting b/testsuite/expect/globals_accounting index 999f6e8cd14..95b90e0d217 100644 --- a/testsuite/expect/globals_accounting +++ b/testsuite/expect/globals_accounting @@ -594,6 +594,7 @@ proc mod_acct { cluster wparent name wdesc worg qos fairshare grpcpumin grpcpu g } set scommand "$scommand qoslevel='$qos'" set assoc_stuff 1 + send_user "qos set to $qos\n" } incr expected $acct_stuff diff --git a/testsuite/expect/test21.26 b/testsuite/expect/test21.26 index b0a58bf4f36..c0e9484a118 100755 --- a/testsuite/expect/test21.26 +++ b/testsuite/expect/test21.26 @@ -35,7 +35,7 @@ source ./globals_accounting set test_id "test21.26" set exit_code 0 -set cluster1 qclustest +set cluster1 [get_cluster_name] set account1 qacctest1 set account2 qacctest2 set qos1 qqostest @@ -62,67 +62,85 @@ if { [string compare [check_accounting_admin_level] "Administrator"] } { exit 0 } +proc end_test { } { + global user1 account1 account2 cluster1 qos1 qos_val + set exit_code 0 + incr exit_code [remove_user "" "" "$user1"] + incr exit_code [remove_acct "" "$account1,$account2"] + incr exit_code [remove_qos "$qos1"] + incr exit_code [mod_acct "$cluster1" "" "root" "" "" "$qos_val" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] +} + + # # remove test associations to make sure we have a clean system # remove_user "" "" "$user1" remove_acct "" "$account1,$account2" remove_qos "$qos1" -remove_cluster "$cluster1" -if {$access_err != 0} { - send_user "\nWARNING: not authorized to perform this test\n" - exit $exit_code + +# get the qos of root on the cluster since we are going to set it to +# nothing here. And put it back at the end of the test. +set match 0 +set my_pid [eval spawn $sacctmgr list cluster $cluster1 format=cluster,qos -np] +expect { + -re "There was a problem" { + send_user "FAILURE: there was a problem with the sacctmgr command\n" + exit 1 + } + -re "$cluster1.(\[a-z,\]*)." { + set qos_val $expect_out(1,string) + set match 1 + exp_continue + } + + timeout { + send_user "\nFAILURE: sacctmgr list associations not responding\n" + slow_kill $my_pid + exit 1 + } + eof { + wait + } +} +if { !$match } { + send_user "\nFAILURE: couldn't query qos\n" + exit 1 } -# Build test associations -#=====Done Cleaning System=========Begin Add Cluster====== -#add cluster -incr exit_code [add_cluster "$cluster1" " " "" "" "" "" "" "" "" "" "" "" ""] +#now set default for cluster to "" +incr exit_code [mod_acct "$cluster1" "" "root" "" "" " " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" remove_qos "$qos1" - remove_cluster "$cluster1" exit $exit_code } -#=====Done Add Cluster========Begin Add QoS========== + + #add qos incr exit_code [add_qos "$qos1"] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" remove_qos "$qos1" - remove_cluster "$cluster1" exit $exit_code } #====Done Add QoS===========Begin Add First Account======== #add default account incr exit_code [add_acct "$cluster1" "" "$account1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } #====Done Add First Account====Begin Add Second Account==== #add account incr exit_code [add_acct "$cluster1" "$account1" "$account2" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } #=====Done Add Second Account========Begin Add User========= #add user incr exit_code [add_user "$cluster1" "$account1,$account2" "$user1" "" "" "$account1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } #====Done add user====Done building test associations===Begin test section======= @@ -159,10 +177,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: Initial sacctmgr add failed with ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -170,10 +185,7 @@ if {$matches != 6} { #modify test1 account to add test QoS incr exit_code [mod_acct "$cluster1" "" "$account1" "" "" "+$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -210,10 +222,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: failed on verify of +$qos1 to account $account1 ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -221,10 +230,7 @@ if {$matches != 6} { #modify test2 account to remove test QoS incr exit_code [mod_acct "$cluster1" "" "$account2" "" "" "-$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -260,10 +266,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: verify of -$qos1 from account $account2 ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -272,10 +275,7 @@ if {$matches != 6} { #modify test1 account to remove test QoS incr exit_code [mod_acct "$cluster1" "" "$account1" "" "" "-$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -311,10 +311,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: verify of -$qos1 from account $account1 ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -322,10 +319,7 @@ if {$matches != 6} { #modify test2 account to add test QoS incr exit_code [mod_acct "$cluster1" "" "$account2" "" "" "+$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -362,10 +356,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: failed on verify of +$qos1 to account $account2 ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -373,10 +364,7 @@ if {$matches != 6} { #modify root account to add test QoS incr exit_code [mod_acct "$cluster1" "" "root" "" "" "+$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -413,10 +401,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: failed on verify of +$qos1 to account root ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -424,10 +409,7 @@ if {$matches != 6} { #modify test2 account to remove test QoS incr exit_code [mod_acct "$cluster1" "" "$account2" "" "" "-$qos1" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""] if { $exit_code } { - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit $exit_code } @@ -464,10 +446,7 @@ expect { if {$matches != 6} { send_user "\nFAILURE: failed on verify of -$qos1 to account $account2 ($matches)\n" - remove_user "" "" "$user1" - remove_acct "" "$account1,$account2" - remove_qos "$qos1" - remove_cluster "$cluster1" + end_test exit 1 } @@ -475,11 +454,7 @@ if {$matches != 6} { #======Done With List====== Ending======= # This is the end below here # -incr exit_code [remove_user "" "" "$user1"] -incr exit_code [remove_acct "" "$account1,$account2"] -incr exit_code [remove_qos "$qos1"] -incr exit_code [remove_cluster "$cluster1"] - +incr exit_code [end_test] if {$exit_code == 0} { send_user "\nSUCCESS: $test_id\n" } else { -- GitLab