diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c index c3e7ed3b8d50b8b1797dbeb620850629529d0efe..1567b39f494caff3818758f74a3fa4e54a4951f6 100644 --- a/src/common/slurm_accounting_storage.c +++ b/src/common/slurm_accounting_storage.c @@ -139,6 +139,8 @@ typedef struct slurm_acct_storage_ops { List selected_steps, List selected_parts, void *params); + List (*get_jobs_cond) (void *db_conn, + acct_job_cond_t *job_cond); void (*job_archive) (void *db_conn, List selected_parts, void *params); int (*update_shares_used) (void *db_conn, @@ -214,6 +216,7 @@ static slurm_acct_storage_ops_t * _acct_storage_get_ops( "jobacct_storage_p_step_complete", "jobacct_storage_p_suspend", "jobacct_storage_p_get_jobs", + "jobacct_storage_p_get_jobs_cond", "jobacct_storage_p_archive", "acct_storage_p_update_shares_used", "acct_storage_p_flush_jobs_on_cluster" @@ -470,6 +473,30 @@ extern void destroy_acct_association_cond(void *object) } } +extern void destroy_acct_job_cond(void *object) +{ + acct_job_cond_t *job_cond = + (acct_job_cond_t *)object; + + if(job_cond) { + if(job_cond->acct_list) + list_destroy(job_cond->acct_list); + if(job_cond->associd_list) + list_destroy(job_cond->associd_list); + if(job_cond->cluster_list) + list_destroy(job_cond->cluster_list); + if(job_cond->groupid_list) + list_destroy(job_cond->groupid_list); + if(job_cond->partition_list) + list_destroy(job_cond->partition_list); + if(job_cond->step_list) + list_destroy(job_cond->step_list); + if(job_cond->user_list) + list_destroy(job_cond->user_list); + xfree(job_cond); + } +} + extern void destroy_acct_update_object(void *object) { acct_update_object_t *acct_update = @@ -1438,6 +1465,212 @@ unpack_error: return SLURM_ERROR; } +extern void pack_acct_job_cond(void *in, Buf buffer) +{ + char *tmp_info = NULL; + jobacct_selected_step_t *job = NULL; + uint32_t count = 0; + + ListIterator itr = NULL; + acct_job_cond_t *object = (acct_job_cond_t *)in; + + if(!object) { + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack16(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + pack32(0, buffer); + return; + } + + if(object->acct_list) + count = list_count(object->acct_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->acct_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + list_iterator_destroy(itr); + } + count = 0; + + if(object->associd_list) + count = list_count(object->associd_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->associd_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + } + count = 0; + + if(object->cluster_list) + count = list_count(object->cluster_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->cluster_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + list_iterator_destroy(itr); + } + count = 0; + + pack16(object->completion, buffer); + + if(object->groupid_list) + count = list_count(object->groupid_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->groupid_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + } + count = 0; + + if(object->partition_list) + count = list_count(object->partition_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->partition_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + list_iterator_destroy(itr); + } + count = 0; + + if(object->step_list) + count = list_count(object->step_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->step_list); + while((job = list_next(itr))) { + pack_jobacct_selected_step(job, buffer); + } + list_iterator_destroy(itr); + } + count = 0; + + pack32(object->usage_end, buffer); + pack32(object->usage_start, buffer); + + if(object->user_list) + count = list_count(object->user_list); + + pack32(count, buffer); + if(count) { + itr = list_iterator_create(object->user_list); + while((tmp_info = list_next(itr))) { + packstr(tmp_info, buffer); + } + list_iterator_destroy(itr); + } + count = 0; +} + +extern int unpack_acct_job_cond(void **object, Buf buffer) +{ + uint32_t uint32_tmp; + int i; + uint32_t count; + acct_job_cond_t *object_ptr = xmalloc(sizeof(acct_job_cond_t)); + char *tmp_info = NULL; + jobacct_selected_step_t *job = NULL; + + *object = object_ptr; + safe_unpack32(&count, buffer); + if(count) { + object_ptr->acct_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->acct_list, tmp_info); + } + } + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->associd_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->associd_list, tmp_info); + } + } + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->cluster_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->cluster_list, tmp_info); + } + } + + safe_unpack16(&object_ptr->completion, buffer); + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->groupid_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->groupid_list, tmp_info); + } + } + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->partition_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->partition_list, tmp_info); + } + } + + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->step_list = + list_create(destroy_jobacct_selected_step); + for(i=0; i<count; i++) { + unpack_jobacct_selected_step(&job, buffer); + list_append(object_ptr->step_list, job); + } + } + + safe_unpack32(&object_ptr->usage_end, buffer); + safe_unpack32(&object_ptr->usage_start, buffer); + + safe_unpack32(&count, buffer); + if(count) { + object_ptr->user_list = list_create(slurm_destroy_char); + for(i=0; i<count; i++) { + safe_unpackstr_xmalloc(&tmp_info, &uint32_tmp, buffer); + list_append(object_ptr->user_list, tmp_info); + } + } + + return SLURM_SUCCESS; + +unpack_error: + destroy_acct_job_cond(object_ptr); + *object = NULL; + return SLURM_ERROR; +} + extern void pack_acct_update_object(acct_update_object_t *object, Buf buffer) { uint32_t count = 0; @@ -2025,6 +2258,20 @@ extern List jobacct_storage_g_get_jobs(void *db_conn, (db_conn, selected_steps, selected_parts, params); } +/* + * get info from the storage + * returns List of job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_g_get_jobs_cond(void *db_conn, + acct_job_cond_t *job_cond) +{ + if (slurm_acct_storage_init(NULL) < 0) + return NULL; + return (*(g_acct_storage_context->ops.get_jobs_cond)) + (db_conn, job_cond); +} + /* * expire old info from the storage */ @@ -2033,7 +2280,8 @@ extern void jobacct_storage_g_archive(void *db_conn, { if (slurm_acct_storage_init(NULL) < 0) return; - (*(g_acct_storage_context->ops.job_archive))(db_conn, selected_parts, params); + (*(g_acct_storage_context->ops.job_archive))(db_conn, selected_parts, + params); return; } diff --git a/src/common/slurm_accounting_storage.h b/src/common/slurm_accounting_storage.h index 6f33806dbdfd69b9dfa93d82d0231a9516ccbc6c..b20d0e3898ddb7ab429d2e100b06f55344e85fc3 100644 --- a/src/common/slurm_accounting_storage.h +++ b/src/common/slurm_accounting_storage.h @@ -156,12 +156,13 @@ typedef struct { char *control_host; uint32_t control_port; uint32_t default_fairshare; /* fairshare number */ - uint32_t default_max_cpu_secs_per_job; /* max number of cpu seconds this - * association can have per job */ - uint32_t default_max_jobs; /* max number of jobs this association can run - * at one time */ + uint32_t default_max_cpu_secs_per_job;/* max number of cpu seconds this + * association can have per job */ + uint32_t default_max_jobs;/* max number of jobs this association can run + * at one time */ uint32_t default_max_nodes_per_job; /* max number of nodes this - * association can allocate per job */ + * association can + * allocate per job */ uint32_t default_max_wall_duration_per_job; /* longest time this * association can run a job */ char *name; @@ -173,6 +174,20 @@ typedef struct { uint16_t sub_acct; } acct_coord_rec_t; +typedef struct { + List acct_list; /* list of char * */ + List associd_list; /* list of char */ + List cluster_list; /* list of char * */ + uint16_t completion; /* get job completion records instead + * of accounting record */ + List groupid_list; /* list of char * */ + List partition_list; /* list of char * */ + List step_list; /* list of jobacct_selected_step_t */ + uint32_t usage_end; + uint32_t usage_start; + List user_list; /* list of char * */ +} acct_job_cond_t; + typedef struct { acct_admin_level_t admin_level; acct_association_cond_t *assoc_cond; @@ -224,10 +239,12 @@ extern void destroy_acct_user_cond(void *object); extern void destroy_acct_account_cond(void *object); extern void destroy_acct_cluster_cond(void *object); extern void destroy_acct_association_cond(void *object); +extern void destroy_acct_job_cond(void *object); extern void destroy_acct_update_object(void *object); extern void destroy_update_shares_rec(void *object); + /* pack functions */ extern void pack_acct_user_rec(void *object, Buf buffer); extern int unpack_acct_user_rec(void **object, Buf buffer); @@ -252,6 +269,8 @@ extern void pack_acct_cluster_cond(void *object, Buf buffer); extern int unpack_acct_cluster_cond(void **object, Buf buffer); extern void pack_acct_association_cond(void *object, Buf buffer); extern int unpack_acct_association_cond(void **object, Buf buffer); +extern void pack_acct_job_cond(void *object, Buf buffer); +extern int unpack_acct_job_cond(void **object, Buf buffer); extern void pack_acct_update_object(acct_update_object_t *object, Buf buffer); extern int unpack_acct_update_object(acct_update_object_t **object, Buf buffer); @@ -561,6 +580,14 @@ extern List jobacct_storage_g_get_jobs(void *db_conn, List selected_parts, void *params); +/* + * get info from the storage + * returns List of jobacct_job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_g_get_jobs_cond(void *db_conn, + acct_job_cond_t *job_cond); + /* * expire old info from the storage */ diff --git a/src/common/slurmdbd_defs.c b/src/common/slurmdbd_defs.c index 3e0fdf3120d6e555ea9fb2af8d1f6fb093563120..869eee2caee2e6bca065ded7d604d069dcfa0537 100644 --- a/src/common/slurmdbd_defs.c +++ b/src/common/slurmdbd_defs.c @@ -360,6 +360,7 @@ extern Buf pack_slurmdbd_msg(slurmdbd_msg_t *req) case DBD_GET_ACCOUNTS: case DBD_GET_ASSOCS: case DBD_GET_CLUSTERS: + case DBD_GET_JOBS_COND: case DBD_GET_USERS: case DBD_REMOVE_ACCOUNTS: case DBD_REMOVE_ASSOCS: @@ -475,6 +476,7 @@ extern int unpack_slurmdbd_msg(slurmdbd_msg_t *resp, Buf buffer) case DBD_GET_ACCOUNTS: case DBD_GET_ASSOCS: case DBD_GET_CLUSTERS: + case DBD_GET_JOBS_COND: case DBD_GET_USERS: case DBD_REMOVE_ACCOUNTS: case DBD_REMOVE_ASSOCS: @@ -1240,6 +1242,9 @@ void inline slurmdbd_free_cond_msg(slurmdbd_msg_type_t type, case DBD_REMOVE_CLUSTERS: my_destroy = destroy_acct_cluster_cond; break; + case DBD_GET_JOBS: + my_destroy = destroy_acct_job_cond; + break; case DBD_GET_USERS: case DBD_REMOVE_USERS: my_destroy = destroy_acct_user_cond; @@ -1497,6 +1502,8 @@ void inline slurmdbd_pack_cond_msg(slurmdbd_msg_type_t type, case DBD_REMOVE_CLUSTERS: my_function = pack_acct_cluster_cond; break; + case DBD_GET_JOBS: + my_function = pack_acct_job_cond; case DBD_GET_USERS: case DBD_REMOVE_USERS: my_function = pack_acct_user_cond; @@ -1528,6 +1535,9 @@ int inline slurmdbd_unpack_cond_msg(slurmdbd_msg_type_t type, case DBD_REMOVE_CLUSTERS: my_function = unpack_acct_cluster_cond; break; + case DBD_GET_JOBS: + my_function = unpack_acct_job_cond; + break; case DBD_GET_USERS: case DBD_REMOVE_USERS: my_function = unpack_acct_user_cond; diff --git a/src/common/slurmdbd_defs.h b/src/common/slurmdbd_defs.h index b866355110d59b8aac864e9397836676b4b4a8fa..9a97af1e14a45f193d9acd625205c3e30fde1f74 100644 --- a/src/common/slurmdbd_defs.h +++ b/src/common/slurmdbd_defs.h @@ -99,7 +99,7 @@ typedef enum { DBD_RC, /* Return code from operation */ DBD_REGISTER_CTLD, /* Register a slurmctld's comm port */ DBD_REMOVE_ACCOUNTS, /* Remove existing account */ - DBD_REMOVE_ACCOUNT_COORDS,/* Remove existing coordinatior from + DBD_REMOVE_ACCOUNT_COORDS,/* Remove existing coordinator from * an account */ DBD_REMOVE_ASSOCS, /* Remove existing association */ DBD_REMOVE_CLUSTERS, /* Remove existing cluster */ @@ -107,7 +107,8 @@ typedef enum { DBD_ROLL_USAGE, /* Roll up usage */ DBD_STEP_COMPLETE, /* Record step completion */ DBD_STEP_START, /* Record step starting */ - DBD_UPDATE_SHARES_USED /* Record current share usage */ + DBD_UPDATE_SHARES_USED, /* Record current share usage */ + DBD_GET_JOBS_COND /* Get job information with a condition */ } slurmdbd_msg_type_t; /*****************************************************************************\ diff --git a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c index 1e95e1baea91e962b6b6e912bafa40f76fe1f0ae..705791d7c97dd8fe3c1cbc2b40d3e8e163ceab88 100644 --- a/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c +++ b/src/plugins/accounting_storage/filetxt/accounting_storage_filetxt.c @@ -805,6 +805,37 @@ extern List jobacct_storage_p_get_jobs(void *db_conn, params); } +/* + * get info from the storage + * returns List of jobacct_job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(void *db_conn, + acct_job_cond_t *job_cond) +{ + sacct_parameters_t params; + + memset(¶ms, 0, sizeof(sacct_parameters_t)); + params.opt_uid = -1; + + if(job_cond->cluster_list && list_count(job_cond->cluster_list)) { + params.cluster = list_pop(job_cond->cluster_list); + } + if(job_cond->user_list && list_count(job_cond->user_list)) { + char *user = list_pop(job_cond->user_list); + struct passwd *pw = NULL; + if ((pw=getpwnam(user))) + params.opt_uid = pw->pw_uid; + xfree(user); + } + + return filetxt_jobacct_process_get_jobs(job_cond->step_list, + job_cond->partition_list, + ¶ms); + if(params.cluster) + xfree(params.cluster); +} + /* * expire old info from the storage */ diff --git a/src/plugins/accounting_storage/gold/accounting_storage_gold.c b/src/plugins/accounting_storage/gold/accounting_storage_gold.c index 1697520cdedaa08710828d1737ec7664b98a9372..3c5fca395af952c35a180f665c3756ba42081d5a 100644 --- a/src/plugins/accounting_storage/gold/accounting_storage_gold.c +++ b/src/plugins/accounting_storage/gold/accounting_storage_gold.c @@ -3240,6 +3240,18 @@ extern List jobacct_storage_p_get_jobs(void *db_conn, return job_list; } +/* + * get info from the storage + * returns List of jobacct_job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(void *db_conn, + void *job_cond) +{ + info("not implemented"); + return NULL; +} + /* * expire old info from the storage */ diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index 67a9718af13cb9dba53c9593e3c94fa18f21cc11..3a2964dd7f653bd4ed9b74d71cb6ac29bfc63c12 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -5675,7 +5675,57 @@ extern int jobacct_storage_p_suspend(mysql_conn_t *mysql_conn, extern List jobacct_storage_p_get_jobs(mysql_conn_t *mysql_conn, List selected_steps, List selected_parts, - void *params) + sacct_parameters_t *params) +{ + List job_list = NULL; +#ifdef HAVE_MYSQL + acct_job_cond_t job_cond; + struct passwd *pw = NULL; + + if(!mysql_conn) { + error("We need a connection to run this"); + return NULL; + } else if(!mysql_conn->acct_mysql_db + || mysql_db_ping(mysql_conn->acct_mysql_db) != 0) { + if(mysql_get_db_connection(&mysql_conn->acct_mysql_db, + mysql_db_name, mysql_db_info) + != SLURM_SUCCESS) { + error("unable to re-connect to mysql database"); + return NULL; + } + } + memset(&job_cond, 0, sizeof(acct_job_cond_t)); + + job_cond.step_list = selected_steps; + job_cond.partition_list = selected_parts; + if(params->opt_cluster) { + job_cond.cluster_list = list_create(NULL); + list_append(job_cond.cluster_list, params->opt_cluster); + } + + if (params->opt_uid >=0 && (pw=getpwuid(params->opt_uid))) { + job_cond.user_list = list_create(NULL); + list_append(job_cond.user_list, pw->pw_name); + } + + job_list = mysql_jobacct_process_get_jobs(mysql_conn, &job_cond); + + if(job_cond.user_list) + list_destroy(job_cond.user_list); + if(job_cond.cluster_list) + list_destroy(job_cond.cluster_list); + +#endif + return job_list; +} + +/* + * get info from the storage + * returns List of job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(mysql_conn_t *mysql_conn, + acct_job_cond_t *job_cond) { List job_list = NULL; #ifdef HAVE_MYSQL @@ -5691,10 +5741,7 @@ extern List jobacct_storage_p_get_jobs(mysql_conn_t *mysql_conn, return NULL; } } - job_list = mysql_jobacct_process_get_jobs(mysql_conn, - selected_steps, - selected_parts, - params); + job_list = mysql_jobacct_process_get_jobs(mysql_conn, job_cond); #endif return job_list; } diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c index 426c30ef1807290173970b5c6160878def4bc856..2ef19382e8837d7772c919680f49145ba8b1811f 100644 --- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c +++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c @@ -45,25 +45,19 @@ #include "mysql_jobacct_process.h" #ifdef HAVE_MYSQL -static void _do_fdump(List job_list) -{ - info("fdump option not applicable from mysql plugin"); - return; -} extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, - List selected_steps, - List selected_parts, - sacct_parameters_t *params) + acct_job_cond_t *job_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; - char *selected_part = NULL; + char *object = NULL; jobacct_selected_step_t *selected_step = NULL; ListIterator itr = NULL; - int set = 0; + int set = 0, assoc_set=0; + char *table_level="t2"; MYSQL_RES *result = NULL, *step_result = NULL; MYSQL_ROW row, step_row; int i; @@ -97,7 +91,9 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, "t1.alloc_cpus", "t1.nodelist", "t1.kill_requid", - "t1.qos" + "t1.qos", + "t2.user", + "t2.cluster" }; /* if this changes you will need to edit the corresponding @@ -159,6 +155,8 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, JOB_REQ_NODELIST, JOB_REQ_KILL_REQUID, JOB_REQ_QOS, + JOB_REQ_USER_NAME, + JOB_REQ_CLUSTER, JOB_REQ_COUNT }; enum { @@ -195,62 +193,175 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, STEP_REQ_COUNT }; - if(selected_steps && list_count(selected_steps)) { + if(!job_cond) + goto no_cond; + + /* THIS ASSOCID CHECK ALWAYS NEEDS TO BE FIRST!!!!!!! */ + if(job_cond->associd_list && list_count(job_cond->associd_list)) { + set = 0; + xstrfmtcat(extra, ", %s as t3 where ("); + itr = list_iterator_create(job_cond->associd_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "t3.id=%s", object); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + assoc_set=1; + table_level="t3"; + /* just incase the association is gone */ + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "t3.id is null) && " + "(t2.lft between t3.lft and t3.rgt " + "|| t2.lft is null)"); + } + + if(job_cond->acct_list && list_count(job_cond->acct_list)) { set = 0; if(extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); - itr = list_iterator_create(selected_steps); - while((selected_step = list_next(itr))) { + itr = list_iterator_create(job_cond->acct_list); + while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - tmp = xstrdup_printf("t1.jobid=%u", - selected_step->jobid); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.acct='%s'", object); set = 1; - xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } - if(selected_parts && list_count(selected_parts)) { + if(job_cond->groupid_list && list_count(job_cond->groupid_list)) { set = 0; if(extra) xstrcat(extra, " && ("); else xstrcat(extra, " where ("); - itr = list_iterator_create(selected_parts); - while((selected_part = list_next(itr))) { + itr = list_iterator_create(job_cond->groupid_list); + while((object = list_next(itr))) { if(set) xstrcat(extra, " || "); - tmp = xstrdup_printf("t1.partition='%s'", - selected_part); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.gid=", object); set = 1; - xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } - - for(i=0; i<JOB_REQ_COUNT; i++) { - if(i) - xstrcat(tmp, ", "); - xstrcat(tmp, job_req_inx[i]); + + if(job_cond->partition_list && list_count(job_cond->partition_list)) { + set = 0; + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->partition_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "t1.partition='%s'", object); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + + if(job_cond->step_list && list_count(job_cond->step_list)) { + set = 0; + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->step_list); + while((selected_step = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "t1.jobid=%u", selected_step->jobid); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + + if(job_cond->usage_start) { + if(!job_cond->usage_end) + job_cond->usage_end = time(NULL); + + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " where ("); + xstrfmtcat(extra, + "(t1.eligible < %d && (end >= %d || end = 0)))", + job_cond->usage_end, job_cond->usage_start); + } + + /* we need to put all the associations (t2) stuff together here */ + if(job_cond->cluster_list && list_count(job_cond->cluster_list)) { + set = 0; + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " where ("); + + itr = list_iterator_create(job_cond->cluster_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "%s.cluster='%s'", + table_level, object); + set = 1; + } + list_iterator_destroy(itr); + /* just incase the association is gone */ + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "%s.cluster is null)", table_level); + } + + if(job_cond->user_list && list_count(job_cond->user_list)) { + set = 0; + if(extra) + xstrcat(extra, " && ("); + else + xstrcat(extra, " where ("); + + itr = list_iterator_create(job_cond->user_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "%s.user='%s'", table_level, object); + set = 1; + } + list_iterator_destroy(itr); + /* just incase the association is gone */ + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "%s.user is null)", table_level); + } + +no_cond: + + xfree(tmp); + xstrfmtcat(tmp, "%s", job_req_inx[0]); + for(i=1; i<JOB_REQ_COUNT; i++) { + xstrfmtcat(tmp, ", %s", job_req_inx[i]); } - query = xstrdup_printf("select %s from %s t1", - tmp, job_table); + query = xstrdup_printf("select %s from %s as t1 left join %s as t2 " + "on t1.associd=t2.id", + tmp, job_table, assoc_table); xfree(tmp); - if(extra) { xstrcat(query, extra); xfree(extra); } - - //info("query = %s", query); + + debug3("%d query\n%s", mysql_conn->conn, query); if(!(result = mysql_db_query_ret( mysql_conn->acct_mysql_db, query, 0))) { xfree(query); @@ -261,31 +372,20 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, while((row = mysql_fetch_row(result))) { char *id = row[JOB_REQ_ID]; - acct_association_rec_t account_rec; - memset(&account_rec, 0, sizeof(acct_association_rec_t)); + job = create_jobacct_job_rec(); job->alloc_cpus = atoi(row[JOB_REQ_ALLOC_CPUS]); - account_rec.id = job->associd = atoi(row[JOB_REQ_ASSOCID]); - assoc_mgr_fill_in_assoc(mysql_conn, &account_rec, 0, NULL); - if(account_rec.cluster) { - if(params->opt_cluster && - strcmp(params->opt_cluster, account_rec.cluster)) { - destroy_jobacct_job_rec(job); - job = NULL; - continue; - } - job->cluster = xstrdup(account_rec.cluster); - } + job->associd = atoi(row[JOB_REQ_ASSOCID]); + + job->cluster = xstrdup(row[JOB_REQ_CLUSTER]); - if(account_rec.user) - job->user = xstrdup(account_rec.user); + if(row[JOB_REQ_USER_NAME]) + job->user = xstrdup(row[JOB_REQ_USER_NAME]); else job->uid = atoi(row[JOB_REQ_UID]); - if(account_rec.acct) - job->account = xstrdup(account_rec.acct); - else - job->account = xstrdup(row[JOB_REQ_ACCOUNT]); + + job->account = xstrdup(row[JOB_REQ_ACCOUNT]); job->blockid = xstrdup(row[JOB_REQ_BLOCKID]); @@ -322,9 +422,10 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, list_append(job_list, job); - if(selected_steps && list_count(selected_steps)) { + if(job_cond && job_cond->step_list + && list_count(job_cond->step_list)) { set = 0; - itr = list_iterator_create(selected_steps); + itr = list_iterator_create(job_cond->step_list); while((selected_step = list_next(itr))) { if(selected_step->jobid != job->jobid) { continue; @@ -339,11 +440,9 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, else xstrcat(extra, " && ("); - tmp = xstrdup_printf("t1.stepid=%u", - selected_step->stepid); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.stepid=%u", + selected_step->stepid); set = 1; - xfree(tmp); job->show_full = 0; } list_iterator_destroy(itr); @@ -447,9 +546,6 @@ extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, } mysql_free_result(result); - if (params && params->opt_fdump) - _do_fdump(job_list); - return job_list; } diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h index e9def5417a691a45d6ddf564e04a12befb16e008..efed26af404f2b8ee185b260b3cf82acaa91aeec 100644 --- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h +++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h @@ -66,13 +66,12 @@ typedef struct { //extern int acct_db_init; +extern char *assoc_table; extern char *job_table; extern char *step_table; extern List mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn, - List selected_steps, - List selected_parts, - sacct_parameters_t *params); + acct_job_cond_t *job_cond); extern void mysql_jobacct_process_archive(mysql_conn_t *mysql_conn, List selected_parts, diff --git a/src/plugins/accounting_storage/none/accounting_storage_none.c b/src/plugins/accounting_storage/none/accounting_storage_none.c index 0701440e26b77f8f7577cd08981bfe852ce8e520..9a7dda713501970456681aaf0c9f6aa7fbf225c2 100644 --- a/src/plugins/accounting_storage/none/accounting_storage_none.c +++ b/src/plugins/accounting_storage/none/accounting_storage_none.c @@ -326,6 +326,17 @@ extern List jobacct_storage_p_get_jobs(void *db_conn, return NULL; } +/* + * get info from the storage + * returns List of jobacct_job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(void *db_conn, + sacct_job_cond_t *job_cond) +{ + return NULL; +} + /* * expire old info from the storage */ diff --git a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c index 0219e9517cda9b8fb6586246efe41598626ad738..4f3275e9cf562da64e1bf027f0b7afe7fb78f511 100644 --- a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c +++ b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c @@ -1509,20 +1509,60 @@ extern int jobacct_storage_p_suspend(PGconn *acct_pgsql_db, extern List jobacct_storage_p_get_jobs(PGconn *acct_pgsql_db, List selected_steps, List selected_parts, - void *params) + sacct_parameters_t *params) { List job_list = NULL; #ifdef HAVE_PGSQL + acct_job_cond_t job_cond; + struct passwd *pw = NULL; + + if(!acct_pgsql_db || PQstatus(acct_pgsql_db) != CONNECTION_OK) { + if(!pgsql_get_db_connection(&acct_pgsql_db, + pgsql_db_name, pgsql_db_info)) + return job_list; + } + + memset(&job_cond, 0, sizeof(acct_job_cond_t)); + + job_cond.step_list = selected_steps; + job_cond.partition_list = selected_parts; + if(params->opt_cluster) { + job_cond.cluster_list = list_create(NULL); + list_append(job_cond.cluster_list, params->opt_cluster); + } + + if (params->opt_uid >=0 && (pw=getpwuid(params->opt_uid))) { + job_cond.user_list = list_create(NULL); + list_append(job_cond.user_list, pw->pw_name); + } + + job_list = pgsql_jobacct_process_get_jobs(acct_pgsql_db, &job_cond); + + if(job_cond.user_list) + list_destroy(job_cond.user_list); + if(job_cond.cluster_list) + list_destroy(job_cond.cluster_list); +#endif + return job_list; +} + +/* + * get info from the storage + * returns List of job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(PGconn *acct_pgsql_db, + acct_job_cond_t *job_cond) +{ + List job_list = NULL; +#ifdef HAVE_MYSQL if(!acct_pgsql_db || PQstatus(acct_pgsql_db) != CONNECTION_OK) { if(!pgsql_get_db_connection(&acct_pgsql_db, pgsql_db_name, pgsql_db_info)) return job_list; } - job_list = pgsql_jobacct_process_get_jobs(acct_pgsql_db, - selected_steps, - selected_parts, - params); + job_list = pgsql_jobacct_process_get_jobs(acct_pgsql_db, job_cond); #endif return job_list; } diff --git a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.c b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.c index e62cbdf3d4c2a188e472da0f2763ed064b50234f..da738092b559790b6c29bec53b56977937e2724b 100644 --- a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.c +++ b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.c @@ -44,25 +44,19 @@ #include "pgsql_jobacct_process.h" #ifdef HAVE_PGSQL -static void _do_fdump(List job_list) -{ - info("fdump option not applicable from pgsql plugin"); - return; -} extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, - List selected_steps, - List selected_parts, - sacct_parameters_t *params) + acct_job_cond_t *job_cond) { char *query = NULL; char *extra = NULL; char *tmp = NULL; - char *selected_part = NULL; + char *object = NULL; jobacct_selected_step_t *selected_step = NULL; ListIterator itr = NULL; int set = 0; + char *table_level="t2"; PGresult *result = NULL, *step_result = NULL; int i, j; jobacct_job_rec_t *job = NULL; @@ -96,6 +90,8 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, "t1.nodelist", "t1.kill_requid", "t1.qos", + "t2.user_name", + "t2.cluster" }; /* if this changes you will need to edit the corresponding @@ -157,6 +153,8 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, JOB_REQ_NODELIST, JOB_REQ_KILL_REQUID, JOB_REQ_QOS, + JOB_REQ_USER_NAME, + JOB_REQ_CLUSTER, JOB_REQ_COUNT }; enum { @@ -193,56 +191,175 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, STEP_REQ_COUNT }; - if(selected_steps && list_count(selected_steps)) { + if(!job_cond) + goto no_cond; + + /* THIS ASSOCID CHECK ALWAYS NEEDS TO BE FIRST!!!!!!! */ + if(job_cond->associd_list && list_count(job_cond->associd_list)) { set = 0; - xstrcat(extra, " and ("); - itr = list_iterator_create(selected_steps); - while((selected_step = list_next(itr))) { + xstrfmtcat(extra, ", %s as t3 where ("); + itr = list_iterator_create(job_cond->associd_list); + while((object = list_next(itr))) { if(set) xstrcat(extra, " or "); - tmp = xstrdup_printf("t1.jobid=%u", - selected_step->jobid); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.associd=%s", object); set = 1; - xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); + table_level="t3"; + /* just incase the association is gone */ + if(set) + xstrcat(extra, " || "); + xstrfmtcat(extra, "t3.id is null) and " + "(t2.lft between t3.lft and t3.rgt " + "or t2.lft is null)"); } - if(selected_parts && list_count(selected_parts)) { + if(job_cond->acct_list && list_count(job_cond->acct_list)) { set = 0; - xstrcat(extra, " and ("); - itr = list_iterator_create(selected_parts); - while((selected_part = list_next(itr))) { + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->acct_list); + while((object = list_next(itr))) { if(set) xstrcat(extra, " or "); - tmp = xstrdup_printf("t1.partition='%s'", - selected_part); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.acct='%s'", object); set = 1; - xfree(tmp); } list_iterator_destroy(itr); xstrcat(extra, ")"); } - - for(i=0; i<JOB_REQ_COUNT; i++) { - if(i) - xstrcat(tmp, ", "); - xstrcat(tmp, job_req_inx[i]); + + if(job_cond->groupid_list && list_count(job_cond->groupid_list)) { + set = 0; + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->groupid_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "t1.gid=", object); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + + if(job_cond->partition_list && list_count(job_cond->partition_list)) { + set = 0; + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->partition_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "t1.partition='%s'", object); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + + if(job_cond->step_list && list_count(job_cond->step_list)) { + set = 0; + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + itr = list_iterator_create(job_cond->step_list); + while((selected_step = list_next(itr))) { + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "t1.jobid=%u", selected_step->jobid); + set = 1; + } + list_iterator_destroy(itr); + xstrcat(extra, ")"); + } + + if(job_cond->usage_start) { + if(!job_cond->usage_end) + job_cond->usage_end = time(NULL); + + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + xstrfmtcat(extra, + "(t1.eligible < %d and (end >= %d or end = 0)))", + job_cond->usage_end, job_cond->usage_start); + } + + /* we need to put all the associations (t2) stuff together here */ + if(job_cond->cluster_list && list_count(job_cond->cluster_list)) { + set = 0; + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + + itr = list_iterator_create(job_cond->cluster_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "%s.cluster='%s'", + table_level, object); + set = 1; + } + list_iterator_destroy(itr); + /* just incase the association is gone */ + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "%s.cluster is null)", table_level); + } + + if(job_cond->user_list && list_count(job_cond->user_list)) { + set = 0; + if(extra) + xstrcat(extra, " and ("); + else + xstrcat(extra, " where ("); + + itr = list_iterator_create(job_cond->user_list); + while((object = list_next(itr))) { + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "%s.user_name='%s'", + table_level, object); + set = 1; + } + list_iterator_destroy(itr); + /* just incase the association is gone */ + if(set) + xstrcat(extra, " or "); + xstrfmtcat(extra, "%s.user_name is null)", table_level); + } + +no_cond: + + xfree(tmp); + xstrfmtcat(tmp, "%s", job_req_inx[0]); + for(i=1; i<JOB_REQ_COUNT; i++) { + xstrfmtcat(tmp, ", %s", job_req_inx[i]); } - query = xstrdup_printf("select %s from %s t1", - tmp, job_table); + query = xstrdup_printf("select %s from %s as t1 left join %s as t2 " + "on t1.associd=t2.id", + tmp, job_table, assoc_table); xfree(tmp); - if(extra) { xstrcat(query, extra); xfree(extra); } - //info("query = %s", query); + debug3("query\n%s", query); if(!(result = pgsql_db_query_ret(acct_pgsql_db, query))) { xfree(query); list_destroy(job_list); @@ -252,33 +369,19 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, for (i = 0; i < PQntuples(result); i++) { char *id = PQgetvalue(result, i, JOB_REQ_ID); - acct_association_rec_t account_rec; - memset(&account_rec, 0, sizeof(acct_association_rec_t)); + job = create_jobacct_job_rec(); job->alloc_cpus = atoi(PQgetvalue(result, i, JOB_REQ_ALLOC_CPUS)); job->associd = atoi(PQgetvalue(result, i, JOB_REQ_ASSOCID)); - account_rec.id = job->associd; - assoc_mgr_fill_in_assoc(acct_pgsql_db, &account_rec, 0, NULL); - if(account_rec.cluster) { - if(params->opt_cluster && - strcmp(params->opt_cluster, account_rec.cluster)) { - destroy_jobacct_job_rec(job); - job = NULL; - continue; - } - job->cluster = xstrdup(account_rec.cluster); - } - if(account_rec.user) - job->user = xstrdup(account_rec.user); - else + job->cluster = xstrdup(PQgetvalue(result, i, JOB_REQ_CLUSTER)); + + job->user = xstrdup(PQgetvalue(result, i, JOB_REQ_USER_NAME)); + if(!job->user || !job->user[0]) job->uid = atoi(PQgetvalue(result, i, JOB_REQ_UID)); - if(account_rec.acct) - job->account = xstrdup(account_rec.acct); - else - job->account = xstrdup(PQgetvalue(result, i, - JOB_REQ_ACCOUNT)); + job->account = xstrdup(PQgetvalue(result, i, JOB_REQ_ACCOUNT)); + job->blockid = xstrdup(PQgetvalue(result, i, JOB_REQ_BLOCKID)); job->eligible = atoi(PQgetvalue(result, i, JOB_REQ_SUBMIT)); @@ -316,9 +419,10 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, list_append(job_list, job); - if(selected_steps && list_count(selected_steps)) { + if(job_cond && job_cond->step_list && + list_count(job_cond->step_list)) { set = 0; - itr = list_iterator_create(selected_steps); + itr = list_iterator_create(job_cond->step_list); while((selected_step = list_next(itr))) { if(selected_step->jobid != job->jobid) { continue; @@ -333,11 +437,9 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, else xstrcat(extra, " and ("); - tmp = xstrdup_printf("t1.stepid=%u", - selected_step->stepid); - xstrcat(extra, tmp); + xstrfmtcat(extra, "t1.stepid=%u", + selected_step->stepid); set = 1; - xfree(tmp); job->show_full = 0; } list_iterator_destroy(itr); @@ -475,9 +577,6 @@ extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, } PQclear(result); - if (params && params->opt_fdump) - _do_fdump(job_list); - return job_list; } diff --git a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h index 255f1a9d78a35770f0e8d18634212f3a4a389e98..19575d88b4eb473faec6f15adb4c14a40ef12c4b 100644 --- a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h +++ b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h @@ -55,13 +55,12 @@ #ifdef HAVE_PGSQL +extern char *assoc_table; extern char *job_table; extern char *step_table; extern List pgsql_jobacct_process_get_jobs(PGconn *acct_pgsql_db, - List selected_steps, - List selected_parts, - sacct_parameters_t *params); + acct_job_cond_t *job_cond); extern void pgsql_jobacct_process_archive(PGconn *acct_pgsql_db, List selected_parts, diff --git a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c index 145dcdae91d2a093dcac80b3e02925e3692a43d8..b05297cfc4bc34f222dc51d28b0749478259fdb9 100644 --- a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c +++ b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c @@ -1185,6 +1185,41 @@ extern List jobacct_storage_p_get_jobs(void *db_conn, return job_list; } +/* + * get info from the storage + * returns List of job_rec_t * + * note List needs to be freed when called + */ +extern List jobacct_storage_p_get_jobs_cond(void *db_conn, + acct_job_cond_t *job_cond) +{ + slurmdbd_msg_t req, resp; + dbd_cond_msg_t get_msg; + dbd_list_msg_t *got_msg; + int rc; + List job_list = NULL; + + get_msg.cond = job_cond; + + req.msg_type = DBD_GET_JOBS_COND; + req.data = &get_msg; + rc = slurm_send_recv_slurmdbd_msg(&req, &resp); + + if (rc != SLURM_SUCCESS) + error("slurmdbd: DBD_GET_JOBS_COND failure: %m"); + else if (resp.msg_type != DBD_GOT_JOBS) { + error("slurmdbd: response type not DBD_GOT_JOBS: %u", + resp.msg_type); + } else { + got_msg = (dbd_list_msg_t *) resp.data; + job_list = got_msg->my_list; + got_msg->my_list = NULL; + slurmdbd_free_list_msg(got_msg); + } + + return job_list; +} + /* * Expire old info from the storage * Not applicable for any database diff --git a/src/sacct/options.c b/src/sacct/options.c index c1f56487f46afc58c73cc12ee01096433b83945c..3036ae8d57de01e3dc3e6f172232a4b3a35b1ba8 100644 --- a/src/sacct/options.c +++ b/src/sacct/options.c @@ -1125,10 +1125,9 @@ void do_list(void) do_jobsteps = 0; itr = list_iterator_create(jobs); while((job = list_next(itr))) { - /* FIX ME: this should be handled while getting the - data, not afterwards. + /* This is really handled when we got the data except + for the filetxt plugin so keep it here. */ - if (params.opt_uid >= 0 && (job->uid != params.opt_uid)) continue; if (params.opt_gid >= 0 && (job->gid != params.opt_gid)) diff --git a/src/slurmdbd/proc_req.c b/src/slurmdbd/proc_req.c index 1fda0e2d82363b3226b9245a4dff106852e42bea..7c55e662e8209586bd2c81d69d0ab4efbe10661e 100644 --- a/src/slurmdbd/proc_req.c +++ b/src/slurmdbd/proc_req.c @@ -63,6 +63,7 @@ static int _get_accounts(void *db_conn, Buf in_buffer, Buf *out_buffer); static int _get_assocs(void *db_conn, Buf in_buffer, Buf *out_buffer); static int _get_clusters(void *db_conn, Buf in_buffer, Buf *out_buffer); static int _get_jobs(void *db_conn, Buf in_buffer, Buf *out_buffer); +static int _get_jobs_cond(void *db_conn, Buf in_buffer, Buf *out_buffer); static int _get_usage(uint16_t type, void *db_conn, Buf in_buffer, Buf *out_buffer); static int _get_users(void *db_conn, Buf in_buffer, Buf *out_buffer); @@ -176,6 +177,9 @@ proc_req(void **db_conn, slurm_fd orig_fd, case DBD_GET_JOBS: rc = _get_jobs(*db_conn, in_buffer, out_buffer); break; + case DBD_GET_JOBS_COND: + rc = _get_jobs_cond(*db_conn, in_buffer, out_buffer); + break; case DBD_GET_USERS: rc = _get_users(*db_conn, in_buffer, out_buffer); break; @@ -688,7 +692,13 @@ static int _get_jobs(void *db_conn, Buf in_buffer, Buf *out_buffer) memset(&sacct_params, 0, sizeof(sacct_parameters_t)); sacct_params.opt_cluster = get_jobs_msg->cluster_name; - + sacct_params.opt_uid = -1; + if(get_jobs_msg->user) { + struct passwd *pw = NULL; + if ((pw=getpwnam(get_jobs_msg->user))) + sacct_params.opt_uid = pw->pw_uid; + } + list_msg.my_list = jobacct_storage_g_get_jobs( db_conn, get_jobs_msg->selected_steps, get_jobs_msg->selected_parts, @@ -705,6 +715,35 @@ static int _get_jobs(void *db_conn, Buf in_buffer, Buf *out_buffer) return SLURM_SUCCESS; } +static int _get_jobs_cond(void *db_conn, Buf in_buffer, Buf *out_buffer) +{ + dbd_cond_msg_t *cond_msg = NULL; + dbd_list_msg_t list_msg; + char *comment = NULL; + + debug2("DBD_GET_JOBS_COND: called"); + if (slurmdbd_unpack_cond_msg(DBD_GET_JOBS_COND, &cond_msg, in_buffer) != + SLURM_SUCCESS) { + comment = "Failed to unpack DBD_GET_JOBS_COND message"; + error("%s", comment); + *out_buffer = make_dbd_rc_msg(SLURM_ERROR, comment, + DBD_GET_JOBS_COND); + return SLURM_ERROR; + } + + list_msg.my_list = jobacct_storage_g_get_jobs_cond( + db_conn, cond_msg->cond); + slurmdbd_free_cond_msg(DBD_GET_JOBS_COND, cond_msg); + + *out_buffer = init_buf(1024); + pack16((uint16_t) DBD_GOT_JOBS, *out_buffer); + slurmdbd_pack_list_msg(DBD_GOT_JOBS, &list_msg, *out_buffer); + if(list_msg.my_list) + list_destroy(list_msg.my_list); + + return SLURM_SUCCESS; +} + static int _get_usage(uint16_t type, void *db_conn, Buf in_buffer, Buf *out_buffer) {