diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c index 26d8c647579a7ed0e32e711c4cad1052fa348cbe..d8f9d7fca4afa2efc19f998a4d4cea96f9bdd387 100644 --- a/src/common/assoc_mgr.c +++ b/src/common/assoc_mgr.c @@ -1039,6 +1039,12 @@ extern int assoc_mgr_fill_in_assoc(void *db_conn, acct_association_rec_t *assoc, assoc->max_submit_jobs = ret_assoc->max_submit_jobs; assoc->max_wall_pj = ret_assoc->max_wall_pj; + if(assoc->valid_qos) { + FREE_NULL_BITMAP(assoc->valid_qos); + assoc->valid_qos = bit_copy(ret_assoc->valid_qos); + } else + assoc->valid_qos = ret_assoc->valid_qos; + if(assoc->parent_acct) { xfree(assoc->parent_acct); assoc->parent_acct = xstrdup(ret_assoc->parent_acct); @@ -1116,6 +1122,7 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user, extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos, int enforce, + acct_association_rec_t *assoc_ptr, acct_qos_rec_t **qos_pptr) { ListIterator itr = NULL; @@ -1147,6 +1154,17 @@ extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos, return SLURM_ERROR; else return SLURM_SUCCESS; + } else if(assoc_ptr) { + if(enforce + && (!assoc_ptr->valid_qos + || !bit_test(assoc_ptr->valid_qos, found_qos->id))) { + error("This association %d(account='%s', " + "user='%s', partition='%s' does not have " + "access to qos %s", + assoc_ptr->id, assoc_ptr->acct, assoc_ptr->user, + assoc_ptr->partition, found_qos->name); + return SLURM_ERROR; + } } debug3("found correct qos"); diff --git a/src/common/assoc_mgr.h b/src/common/assoc_mgr.h index a2c3e9dc15e1439dc2bd32378d1a6ad6fef2899f..b2658d20c206c50a32cf58cdb715e67c1df2e0b6 100644 --- a/src/common/assoc_mgr.h +++ b/src/common/assoc_mgr.h @@ -127,6 +127,10 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user, /* * get info from the storage * IN/OUT: qos - acct_qos_rec_t with the id set of the qos. + * IN: assoc_ptr - acct_association_rec_t with the valid_qos + * bitstring avaliable to check against. If this + * is NULL no checking is done, if not NULL we + * validate if this qos is usable by this association. * IN/OUT: qos_pptr - if non-NULL then return a pointer to the * acct_qos record in cache on success * DO NOT FREE. @@ -134,6 +138,7 @@ extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user, */ extern int assoc_mgr_fill_in_qos(void *db_conn, acct_qos_rec_t *qos, int enforce, + acct_association_rec_t *assoc_ptr, acct_qos_rec_t **qos_pptr); /* * get info from the storage diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c index 9da82058f28ec7ad7464c3959e8fa01a0b18c383..0c8404c72abd75d5b50de0169932c515667ebfb3 100644 --- a/src/slurmctld/controller.c +++ b/src/slurmctld/controller.c @@ -1746,20 +1746,6 @@ static void *_assoc_cache_mgr(void *no_data) list_count(job_list)); itr = list_iterator_create(job_list); while ((job_ptr = list_next(itr))) { - if(job_ptr->qos) { - memset(&qos_rec, 0, sizeof(acct_qos_rec_t)); - qos_rec.id = job_ptr->qos; - if((assoc_mgr_fill_in_qos( - acct_db_conn, &qos_rec, - accounting_enforce, - (acct_qos_rec_t **)&job_ptr->qos_ptr)) - != SLURM_SUCCESS) { - verbose("Invalid qos (%u) for job_id %u", - job_ptr->qos, job_ptr->job_id); - /* not a fatal error, qos could have - * been removed */ - } - } if(job_ptr->assoc_id) { memset(&assoc_rec, 0, sizeof(acct_association_rec_t)); assoc_rec.id = job_ptr->assoc_id; @@ -1784,6 +1770,21 @@ static void *_assoc_cache_mgr(void *no_data) job_ptr->assoc_ptr, job_ptr->assoc_id, job_ptr->job_id); } + if(job_ptr->qos) { + memset(&qos_rec, 0, sizeof(acct_qos_rec_t)); + qos_rec.id = job_ptr->qos; + if((assoc_mgr_fill_in_qos( + acct_db_conn, &qos_rec, + accounting_enforce, + NULL, + (acct_qos_rec_t **)&job_ptr->qos_ptr)) + != SLURM_SUCCESS) { + verbose("Invalid qos (%u) for job_id %u", + job_ptr->qos, job_ptr->job_id); + /* not a fatal error, qos could have + * been removed */ + } + } } list_iterator_destroy(itr); unlock_slurmctld(job_write_lock); diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index 89e748bd2580507b1e1b1e9d060621c18a46f934..6771046245e98b045c91e966d3d785e65249aa2d 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -850,19 +850,6 @@ static int _load_job_state(Buf buffer) _add_job_hash(job_ptr); } - if(qos) { - memset(&qos_rec, 0, sizeof(acct_qos_rec_t)); - qos_rec.id = qos; - if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, - accounting_enforce, - (acct_qos_rec_t **) - &job_ptr->qos_ptr)) - != SLURM_SUCCESS) { - verbose("Invalid qos (%u) for job_id %u", qos, job_id); - /* not a fatal error, qos could have been removed */ - } - } - if ((maximum_prio >= priority) && (priority > 1)) maximum_prio = priority; if (job_id_sequence <= job_id) @@ -1009,6 +996,28 @@ static int _load_job_state(Buf buffer) jobacct_storage_g_job_complete(acct_db_conn, job_ptr); } + if(job_ptr->qos) { + memset(&qos_rec, 0, sizeof(acct_qos_rec_t)); + qos_rec.id = job_ptr->qos; + if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, + accounting_enforce, + (acct_association_rec_t *) + job_ptr->assoc_ptr, + (acct_qos_rec_t **) + &job_ptr->qos_ptr)) + != SLURM_SUCCESS) { + info("Cancelling job %u with invalid qos", + job_id); + job_ptr->job_state = JOB_CANCELLED; + job_ptr->state_reason = FAIL_BANK_ACCOUNT; + xfree(job_ptr->state_desc); + if (IS_JOB_PENDING(job_ptr)) + job_ptr->start_time = now; + job_ptr->end_time = now; + job_completion_logger(job_ptr); + } + } + safe_unpack16(&step_flag, buffer); while (step_flag == STEP_FLAG) { /* No need to put these into accounting if they @@ -3349,8 +3358,9 @@ _copy_job_desc_to_job_record(job_desc_msg_t * job_desc, else qos_rec.name = "normal"; } - if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, accounting_enforce, - (acct_qos_rec_t **) &job_ptr->qos_ptr)) + if(assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, accounting_enforce, + (acct_association_rec_t *) job_ptr->assoc_ptr, + (acct_qos_rec_t **) &job_ptr->qos_ptr) != SLURM_SUCCESS) { error("Invalid qos (%s) for job_id %u", qos_rec.name, job_ptr->job_id); @@ -4822,6 +4832,8 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid) if((assoc_mgr_fill_in_qos(acct_db_conn, &qos_rec, accounting_enforce, + (acct_association_rec_t *) + job_ptr->assoc_ptr, (acct_qos_rec_t **) &job_ptr->qos_ptr)) != SLURM_SUCCESS) {