static slurmdb_job_rec_t *_slurmdb_create_job_rec( filetxt_job_rec_t *filetxt_job, slurmdb_job_cond_t *job_cond) { slurmdb_job_rec_t *slurmdb_job = NULL; ListIterator itr = NULL; filetxt_step_rec_t *filetxt_step = NULL; if (!job_cond) goto no_cond; if (job_cond->state_list && list_count(job_cond->state_list)) { char *object = NULL; itr = list_iterator_create(job_cond->state_list); while((object = list_next(itr))) { if (atoi(object) == filetxt_job->status) { list_iterator_destroy(itr); goto foundstate; } } list_iterator_destroy(itr); return NULL; /* no match */ } foundstate: no_cond: slurmdb_job = slurmdb_create_job_rec(); slurmdb_job->associd = 0; slurmdb_job->account = xstrdup(filetxt_job->account); slurmdb_job->blockid = xstrdup(filetxt_job->header.blockid); slurmdb_job->cluster = NULL; slurmdb_job->elapsed = filetxt_job->elapsed; slurmdb_job->eligible = filetxt_job->header.job_submit; slurmdb_job->end = filetxt_job->header.timestamp; slurmdb_job->exitcode = filetxt_job->exitcode; slurmdb_job->gid = filetxt_job->header.gid; slurmdb_job->jobid = filetxt_job->header.jobnum; slurmdb_job->jobname = xstrdup(filetxt_job->jobname); slurmdb_job->partition = xstrdup(filetxt_job->header.partition); slurmdb_job->req_cpus = filetxt_job->ncpus; slurmdb_job->alloc_cpus = filetxt_job->ncpus; if (filetxt_job->nodes) { hostlist_t hl = hostlist_create(filetxt_job->nodes); slurmdb_job->alloc_nodes = hostlist_count(hl); hostlist_destroy(hl); } slurmdb_job->nodes = xstrdup(filetxt_job->nodes); slurmdb_job->priority = filetxt_job->priority; slurmdb_job->requid = filetxt_job->requid; memcpy(&slurmdb_job->stats, &filetxt_job->stats, sizeof(slurmdb_stats_t)); slurmdb_job->show_full = filetxt_job->show_full; slurmdb_job->start = filetxt_job->header.timestamp - slurmdb_job->elapsed; slurmdb_job->state = filetxt_job->status; slurmdb_job->steps = list_create(slurmdb_destroy_step_rec); if (filetxt_job->steps) { itr = list_iterator_create(filetxt_job->steps); while((filetxt_step = list_next(itr))) { slurmdb_step_rec_t *step = _slurmdb_create_step_rec(filetxt_step); if (step) { step->job_ptr = slurmdb_job; if (!slurmdb_job->first_step_ptr) slurmdb_job->first_step_ptr = step; list_append(slurmdb_job->steps, step); } } list_iterator_destroy(itr); } slurmdb_job->submit = filetxt_job->header.job_submit; slurmdb_job->sys_cpu_sec = filetxt_job->rusage.ru_stime.tv_sec; slurmdb_job->sys_cpu_usec = filetxt_job->rusage.ru_stime.tv_usec; slurmdb_job->tot_cpu_sec = filetxt_job->tot_cpu_sec; slurmdb_job->tot_cpu_usec = filetxt_job->tot_cpu_usec; slurmdb_job->track_steps = filetxt_job->track_steps; slurmdb_job->uid = filetxt_job->header.uid; slurmdb_job->user = NULL; slurmdb_job->user_cpu_sec = filetxt_job->rusage.ru_utime.tv_sec; slurmdb_job->user_cpu_usec = filetxt_job->rusage.ru_utime.tv_usec; return slurmdb_job; }
extern int sacctmgr_modify_job(int argc, char *argv[]) { int rc = SLURM_SUCCESS; slurmdb_job_modify_cond_t *job_cond = xmalloc(sizeof( slurmdb_job_modify_cond_t)); slurmdb_job_rec_t *job = slurmdb_create_job_rec(); int i=0; int cond_set = 0, rec_set = 0, set = 0; List ret_list = NULL; for (i=0; i<argc; i++) { int command_len = strlen(argv[i]); if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))) { i++; cond_set += _set_cond(&i, argc, argv, job_cond); } else if (!strncasecmp(argv[i], "Set", MAX(command_len, 3))) { i++; rec_set += _set_rec(&i, argc, argv, job); } else { cond_set += _set_cond(&i, argc, argv, job_cond); } } if (exit_code) { slurmdb_destroy_job_modify_cond(job_cond); slurmdb_destroy_job_rec(job); return SLURM_ERROR; } else if (!rec_set) { exit_code=1; fprintf(stderr, " You didn't give me anything to set\n"); slurmdb_destroy_job_modify_cond(job_cond); slurmdb_destroy_job_rec(job); return SLURM_ERROR; } else if (!cond_set) { if (!commit_check("You didn't set any conditions with 'WHERE'." "\nAre you sure you want to continue?")) { printf("Aborted\n"); slurmdb_destroy_job_modify_cond(job_cond); slurmdb_destroy_job_rec(job); return SLURM_SUCCESS; } } notice_thread_init(); ret_list = acct_storage_g_modify_job(db_conn, my_uid, job_cond, job); if (ret_list && list_count(ret_list)) { char *object = NULL; ListIterator itr = list_iterator_create(ret_list); printf(" Modified jobs...\n"); while((object = list_next(itr))) { printf(" %s\n", object); } list_iterator_destroy(itr); set = 1; } else if (ret_list) { printf(" Nothing modified\n"); rc = SLURM_ERROR; } else { exit_code=1; fprintf(stderr, " Error with request: %s\n", slurm_strerror(errno)); rc = SLURM_ERROR; } FREE_NULL_LIST(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); } } slurmdb_destroy_job_modify_cond(job_cond); slurmdb_destroy_job_rec(job); return rc; }
static int _cluster_get_jobs(mysql_conn_t *mysql_conn, slurmdb_user_rec_t *user, slurmdb_job_cond_t *job_cond, char *cluster_name, char *job_fields, char *step_fields, char *sent_extra, bool is_admin, int only_pending, List sent_list) { char *query = NULL; char *extra = xstrdup(sent_extra); uint16_t private_data = slurm_get_private_data(); slurmdb_selected_step_t *selected_step = NULL; MYSQL_RES *result = NULL, *step_result = NULL; MYSQL_ROW row, step_row; slurmdb_job_rec_t *job = NULL; slurmdb_step_rec_t *step = NULL; time_t now = time(NULL); List job_list = list_create(slurmdb_destroy_job_rec); ListIterator itr = NULL; List local_cluster_list = NULL; int set = 0; char *prefix="t2"; int rc = SLURM_SUCCESS; int last_id = -1, curr_id = -1; local_cluster_t *curr_cluster = NULL; /* This is here to make sure we are looking at only this user * if this flag is set. We also include any accounts they may be * coordinator of. */ if (!is_admin && (private_data & PRIVATE_DATA_JOBS)) { query = xstrdup_printf("select lft from \"%s_%s\" " "where user='******'", cluster_name, assoc_table, user->name); if (user->coord_accts) { slurmdb_coord_rec_t *coord = NULL; itr = list_iterator_create(user->coord_accts); while ((coord = list_next(itr))) { xstrfmtcat(query, " || acct='%s'", coord->name); } list_iterator_destroy(itr); } debug3("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(extra); xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); set = 0; while ((row = mysql_fetch_row(result))) { if (set) { xstrfmtcat(extra, " || (%s between %s.lft and %s.rgt)", row[0], prefix, prefix); } else { set = 1; if (extra) xstrfmtcat(extra, " && ((%s between %s.lft " "and %s.rgt)", row[0], prefix, prefix); else xstrfmtcat(extra, " where ((%s between %s.lft " "and %s.rgt)", row[0], prefix, prefix); } } if (set) xstrcat(extra,")"); mysql_free_result(result); } setup_job_cluster_cond_limits(mysql_conn, job_cond, cluster_name, &extra); query = xstrdup_printf("select %s from \"%s_%s\" as t1 " "left join \"%s_%s\" as t2 " "on t1.id_assoc=t2.id_assoc", job_fields, cluster_name, job_table, cluster_name, assoc_table); if (extra) { xstrcat(query, extra); xfree(extra); } /* Here we want to order them this way in such a way so it is easy to look for duplicates, it is also easy to sort the resized jobs. */ xstrcat(query, " group by id_job, time_submit desc"); debug3("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) { xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); /* Here we set up environment to check used nodes of jobs. Since we store the bitmap of the entire cluster we can use that to set up a hostlist and set up the bitmap to make things work. This should go before the setup of conds since we could update the start/end time. */ if (job_cond && job_cond->used_nodes) { local_cluster_list = setup_cluster_list_with_inx( mysql_conn, job_cond, (void **)&curr_cluster); if (!local_cluster_list) { rc = SLURM_ERROR; goto end_it; } } while ((row = mysql_fetch_row(result))) { char *id = row[JOB_REQ_ID]; bool job_ended = 0; int submit = slurm_atoul(row[JOB_REQ_SUBMIT]); curr_id = slurm_atoul(row[JOB_REQ_JOBID]); if (job_cond && !job_cond->duplicates && (curr_id == last_id) && (slurm_atoul(row[JOB_REQ_STATE]) != JOB_RESIZING)) continue; /* check the bitmap to see if this is one of the jobs we are looking for */ if (!good_nodes_from_inx(local_cluster_list, (void **)&curr_cluster, row[JOB_REQ_NODE_INX], submit)) { last_id = curr_id; continue; } job = slurmdb_create_job_rec(); job->state = slurm_atoul(row[JOB_REQ_STATE]); if (curr_id == last_id) /* put in reverse so we order by the submit getting larger which it is given to us in reverse order from the database */ list_prepend(job_list, job); else list_append(job_list, job); last_id = curr_id; job->alloc_cpus = slurm_atoul(row[JOB_REQ_ALLOC_CPUS]); job->alloc_nodes = slurm_atoul(row[JOB_REQ_ALLOC_NODES]); job->associd = slurm_atoul(row[JOB_REQ_ASSOCID]); job->resvid = slurm_atoul(row[JOB_REQ_RESVID]); job->cluster = xstrdup(cluster_name); /* we want a blank wckey if the name is null */ if (row[JOB_REQ_WCKEY]) job->wckey = xstrdup(row[JOB_REQ_WCKEY]); else job->wckey = xstrdup(""); job->wckeyid = slurm_atoul(row[JOB_REQ_WCKEYID]); if (row[JOB_REQ_USER_NAME]) job->user = xstrdup(row[JOB_REQ_USER_NAME]); else job->uid = slurm_atoul(row[JOB_REQ_UID]); if (row[JOB_REQ_LFT]) job->lft = slurm_atoul(row[JOB_REQ_LFT]); if (row[JOB_REQ_ACCOUNT] && row[JOB_REQ_ACCOUNT][0]) job->account = xstrdup(row[JOB_REQ_ACCOUNT]); else if (row[JOB_REQ_ACCOUNT1] && row[JOB_REQ_ACCOUNT1][0]) job->account = xstrdup(row[JOB_REQ_ACCOUNT1]); if (row[JOB_REQ_BLOCKID]) job->blockid = xstrdup(row[JOB_REQ_BLOCKID]); job->eligible = slurm_atoul(row[JOB_REQ_ELIGIBLE]); job->submit = submit; job->start = slurm_atoul(row[JOB_REQ_START]); job->end = slurm_atoul(row[JOB_REQ_END]); job->timelimit = slurm_atoul(row[JOB_REQ_TIMELIMIT]); /* since the job->end could be set later end it here */ if (job->end) { job_ended = 1; if (!job->start || (job->start > job->end)) job->start = job->end; } if (job_cond && !job_cond->without_usage_truncation && job_cond->usage_start) { if (job->start && (job->start < job_cond->usage_start)) job->start = job_cond->usage_start; if (!job->end || job->end > job_cond->usage_end) job->end = job_cond->usage_end; if (!job->start) job->start = job->end; job->elapsed = job->end - job->start; if (row[JOB_REQ_SUSPENDED]) { MYSQL_RES *result2 = NULL; MYSQL_ROW row2; /* get the suspended time for this job */ query = xstrdup_printf( "select time_start, time_end from " "\"%s_%s\" where " "(time_start < %ld && (time_end >= %ld " "|| time_end = 0)) && job_db_inx=%s " "order by time_start", cluster_name, suspend_table, job_cond->usage_end, job_cond->usage_start, id); debug4("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(result2 = mysql_db_query_ret( mysql_conn, query, 0))) { list_destroy(job_list); job_list = NULL; break; } xfree(query); while ((row2 = mysql_fetch_row(result2))) { time_t local_start = slurm_atoul(row2[0]); time_t local_end = slurm_atoul(row2[1]); if (!local_start) continue; if (job->start > local_start) local_start = job->start; if (job->end < local_end) local_end = job->end; if ((local_end - local_start) < 1) continue; job->elapsed -= (local_end - local_start); job->suspended += (local_end - local_start); } mysql_free_result(result2); } } else { job->suspended = slurm_atoul(row[JOB_REQ_SUSPENDED]); /* fix the suspended number to be correct */ if (job->state == JOB_SUSPENDED) job->suspended = now - job->suspended; if (!job->start) { job->elapsed = 0; } else if (!job->end) { job->elapsed = now - job->start; } else { job->elapsed = job->end - job->start; } job->elapsed -= job->suspended; } if ((int)job->elapsed < 0) job->elapsed = 0; job->jobid = curr_id; job->jobname = xstrdup(row[JOB_REQ_NAME]); job->gid = slurm_atoul(row[JOB_REQ_GID]); job->exitcode = slurm_atoul(row[JOB_REQ_EXIT_CODE]); job->derived_ec = slurm_atoul(row[JOB_REQ_DERIVED_EC]); job->derived_es = xstrdup(row[JOB_REQ_DERIVED_ES]); if (row[JOB_REQ_PARTITION]) job->partition = xstrdup(row[JOB_REQ_PARTITION]); if (row[JOB_REQ_NODELIST]) job->nodes = xstrdup(row[JOB_REQ_NODELIST]); if (!job->nodes || !strcmp(job->nodes, "(null)")) { xfree(job->nodes); job->nodes = xstrdup("(unknown)"); } job->track_steps = slurm_atoul(row[JOB_REQ_TRACKSTEPS]); job->priority = slurm_atoul(row[JOB_REQ_PRIORITY]); job->req_cpus = slurm_atoul(row[JOB_REQ_REQ_CPUS]); job->requid = slurm_atoul(row[JOB_REQ_KILL_REQUID]); job->qosid = slurm_atoul(row[JOB_REQ_QOS]); job->show_full = 1; if (only_pending || (job_cond && job_cond->without_steps)) goto skip_steps; if (job_cond && job_cond->step_list && list_count(job_cond->step_list)) { set = 0; itr = list_iterator_create(job_cond->step_list); while ((selected_step = list_next(itr))) { if (selected_step->jobid != job->jobid) { continue; } else if (selected_step->stepid == NO_VAL) { job->show_full = 1; break; } else if (selected_step->stepid == INFINITE) selected_step->stepid = SLURM_BATCH_SCRIPT; if (set) xstrcat(extra, " || "); else xstrcat(extra, " && ("); /* The stepid could be -2 so use %d not %u */ xstrfmtcat(extra, "t1.id_step=%d", selected_step->stepid); set = 1; job->show_full = 0; } list_iterator_destroy(itr); if (set) xstrcat(extra, ")"); } query = xstrdup_printf("select %s from \"%s_%s\" as t1 " "where t1.job_db_inx=%s", step_fields, cluster_name, step_table, id); if (extra) { xstrcat(query, extra); xfree(extra); } debug4("%d(%s:%d) query\n%s", mysql_conn->conn, THIS_FILE, __LINE__, query); if (!(step_result = mysql_db_query_ret( mysql_conn, query, 0))) { xfree(query); rc = SLURM_ERROR; goto end_it; } xfree(query); /* Querying the steps in the fashion was faster than doing only 1 query and then matching the steps up later with the job. */ while ((step_row = mysql_fetch_row(step_result))) { /* check the bitmap to see if this is one of the steps we are looking for */ if (!good_nodes_from_inx(local_cluster_list, (void **)&curr_cluster, step_row[STEP_REQ_NODE_INX], submit)) continue; step = slurmdb_create_step_rec(); step->tot_cpu_sec = 0; step->tot_cpu_usec = 0; step->job_ptr = job; if (!job->first_step_ptr) job->first_step_ptr = step; list_append(job->steps, step); step->stepid = slurm_atoul(step_row[STEP_REQ_STEPID]); /* info("got step %u.%u", */ /* job->header.jobnum, step->stepnum); */ step->state = slurm_atoul(step_row[STEP_REQ_STATE]); step->exitcode = slurm_atoul(step_row[STEP_REQ_EXIT_CODE]); step->ncpus = slurm_atoul(step_row[STEP_REQ_CPUS]); step->nnodes = slurm_atoul(step_row[STEP_REQ_NODES]); step->ntasks = slurm_atoul(step_row[STEP_REQ_TASKS]); step->task_dist = slurm_atoul(step_row[STEP_REQ_TASKDIST]); if (!step->ntasks) step->ntasks = step->ncpus; step->start = slurm_atoul(step_row[STEP_REQ_START]); step->end = slurm_atoul(step_row[STEP_REQ_END]); /* if the job has ended end the step also */ if (!step->end && job_ended) { step->end = job->end; step->state = job->state; } if (job_cond && !job_cond->without_usage_truncation && job_cond->usage_start) { if (step->start && (step->start < job_cond->usage_start)) step->start = job_cond->usage_start; if (!step->start && step->end) step->start = step->end; if (!step->end || (step->end > job_cond->usage_end)) step->end = job_cond->usage_end; } /* figure this out by start stop */ step->suspended = slurm_atoul(step_row[STEP_REQ_SUSPENDED]); if (!step->end) { step->elapsed = now - step->start; } else { step->elapsed = step->end - step->start; } step->elapsed -= step->suspended; if ((int)step->elapsed < 0) step->elapsed = 0; step->user_cpu_sec = slurm_atoul(step_row[STEP_REQ_USER_SEC]); step->user_cpu_usec = slurm_atoul(step_row[STEP_REQ_USER_USEC]); step->sys_cpu_sec = slurm_atoul(step_row[STEP_REQ_SYS_SEC]); step->sys_cpu_usec = slurm_atoul(step_row[STEP_REQ_SYS_USEC]); step->tot_cpu_sec += step->user_cpu_sec + step->sys_cpu_sec; step->tot_cpu_usec += step->user_cpu_usec + step->sys_cpu_usec; step->stats.vsize_max = slurm_atoul(step_row[STEP_REQ_MAX_VSIZE]); step->stats.vsize_max_taskid = slurm_atoul(step_row[STEP_REQ_MAX_VSIZE_TASK]); step->stats.vsize_ave = atof(step_row[STEP_REQ_AVE_VSIZE]); step->stats.rss_max = slurm_atoul(step_row[STEP_REQ_MAX_RSS]); step->stats.rss_max_taskid = slurm_atoul(step_row[STEP_REQ_MAX_RSS_TASK]); step->stats.rss_ave = atof(step_row[STEP_REQ_AVE_RSS]); step->stats.pages_max = slurm_atoul(step_row[STEP_REQ_MAX_PAGES]); step->stats.pages_max_taskid = slurm_atoul(step_row[STEP_REQ_MAX_PAGES_TASK]); step->stats.pages_ave = atof(step_row[STEP_REQ_AVE_PAGES]); step->stats.cpu_min = slurm_atoul(step_row[STEP_REQ_MIN_CPU]); step->stats.cpu_min_taskid = slurm_atoul(step_row[STEP_REQ_MIN_CPU_TASK]); step->stats.cpu_ave = atof(step_row[STEP_REQ_AVE_CPU]); step->stepname = xstrdup(step_row[STEP_REQ_NAME]); step->nodes = xstrdup(step_row[STEP_REQ_NODELIST]); step->stats.vsize_max_nodeid = slurm_atoul(step_row[STEP_REQ_MAX_VSIZE_NODE]); step->stats.rss_max_nodeid = slurm_atoul(step_row[STEP_REQ_MAX_RSS_NODE]); step->stats.pages_max_nodeid = slurm_atoul(step_row[STEP_REQ_MAX_PAGES_NODE]); step->stats.cpu_min_nodeid = slurm_atoul(step_row[STEP_REQ_MIN_CPU_NODE]); step->requid = slurm_atoul(step_row[STEP_REQ_KILL_REQUID]); } mysql_free_result(step_result); if (!job->track_steps) { /* If we don't have track_steps we want to see if we have multiple steps. If we only have 1 step check the job name against the step name in most all cases it will be different. If it is different print out the step separate. */ if (list_count(job->steps) > 1) job->track_steps = 1; else if (step && step->stepname && job->jobname) { if (strcmp(step->stepname, job->jobname)) job->track_steps = 1; } } skip_steps: /* need to reset here to make the above test valid */ step = NULL; } mysql_free_result(result); end_it: if (local_cluster_list) list_destroy(local_cluster_list); if (rc == SLURM_SUCCESS) list_transfer(sent_list, job_list); list_destroy(job_list); return rc; }