/* * Create an srun job structure from a resource allocation response msg */ static srun_job_t * _job_create_structure(allocation_info_t *ainfo) { srun_job_t *job = xmalloc(sizeof(srun_job_t)); int i; _set_ntasks(ainfo); debug2("creating job with %d tasks", opt.ntasks); slurm_mutex_init(&job->state_mutex); pthread_cond_init(&job->state_cond, NULL); job->state = SRUN_JOB_INIT; job->nodelist = xstrdup(ainfo->nodelist); job->stepid = ainfo->stepid; #if defined HAVE_BGQ //#if defined HAVE_BGQ && defined HAVE_BG_FILES job->nhosts = ainfo->nnodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &job->nhosts); #elif defined HAVE_FRONT_END /* Limited job step support */ opt.overcommit = true; job->nhosts = 1; #else job->nhosts = ainfo->nnodes; #endif #if !defined HAVE_FRONT_END || (defined HAVE_BGQ) //#if !defined HAVE_FRONT_END || (defined HAVE_BGQ && defined HAVE_BG_FILES) if(opt.min_nodes > job->nhosts) { error("Only allocated %d nodes asked for %d", job->nhosts, opt.min_nodes); if (opt.exc_nodes) { /* When resources are pre-allocated and some nodes * are explicitly excluded, this error can occur. */ error("Are required nodes explicitly excluded?"); } return NULL; } if ((ainfo->cpus_per_node == NULL) || (ainfo->cpu_count_reps == NULL)) { error("cpus_per_node array is not set"); return NULL; } #endif job->select_jobinfo = ainfo->select_jobinfo; job->jobid = ainfo->jobid; job->ntasks = opt.ntasks; for (i=0; i<ainfo->num_cpu_groups; i++) { job->cpu_count += ainfo->cpus_per_node[i] * ainfo->cpu_count_reps[i]; } job->rc = -1; job_update_io_fnames(job); return (job); }
extern int clusteracct_storage_g_node_up(void *db_conn, struct node_record *node_ptr, time_t event_time) { if (slurm_acct_storage_init(NULL) < 0) return SLURM_ERROR; /* on some systems we need to make sure we don't say something is completely up if there are cpus in an error state */ if(node_ptr->select_nodeinfo) { uint16_t err_cpus = 0; select_g_select_nodeinfo_get(node_ptr->select_nodeinfo, SELECT_NODEDATA_SUBCNT, NODE_STATE_ERROR, &err_cpus); if(err_cpus) { char *reason = "Setting partial node down."; struct node_record send_node; struct config_record config_rec; uint16_t cpu_cnt = 0; select_g_alter_node_cnt(SELECT_GET_NODE_CPU_CNT, &cpu_cnt); err_cpus *= cpu_cnt; memset(&send_node, 0, sizeof(struct node_record)); memset(&config_rec, 0, sizeof(struct config_record)); send_node.name = node_ptr->name; send_node.config_ptr = &config_rec; send_node.cpus = err_cpus; config_rec.cpus = err_cpus; send_node.node_state = NODE_STATE_ERROR; return (*(g_acct_storage_context->ops.node_down)) (db_conn, &send_node, event_time, reason, slurm_get_slurm_user_id()); } } return (*(g_acct_storage_context->ops.node_up)) (db_conn, node_ptr, event_time); }
/* * pack_part - dump all configuration information about a specific partition * in machine independent form (for network transmission) * IN part_ptr - pointer to partition for which information is requested * IN/OUT buffer - buffer in which data is placed, pointers automatically * updated * global: default_part_loc - pointer to the default partition * NOTE: if you make any changes here be sure to make the corresponding changes * to _unpack_partition_info_members() in common/slurm_protocol_pack.c */ void pack_part(struct part_record *part_ptr, Buf buffer, uint16_t protocol_version) { uint32_t altered; if (protocol_version >= SLURM_2_6_PROTOCOL_VERSION) { if (default_part_loc == part_ptr) part_ptr->flags |= PART_FLAG_DEFAULT; else part_ptr->flags &= (~PART_FLAG_DEFAULT); packstr(part_ptr->name, buffer); pack32(part_ptr->grace_time, buffer); pack32(part_ptr->max_time, buffer); pack32(part_ptr->default_time, buffer); pack32(part_ptr->max_nodes_orig, buffer); pack32(part_ptr->min_nodes_orig, buffer); altered = part_ptr->total_nodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &altered); pack32(altered, buffer); pack32(part_ptr->total_cpus, buffer); pack32(part_ptr->def_mem_per_cpu, buffer); pack32(part_ptr->max_cpus_per_node, buffer); pack32(part_ptr->max_mem_per_cpu, buffer); pack16(part_ptr->flags, buffer); pack16(part_ptr->max_share, buffer); pack16(part_ptr->preempt_mode, buffer); pack16(part_ptr->priority, buffer); pack16(part_ptr->state_up, buffer); pack16(part_ptr->cr_type, buffer); packstr(part_ptr->allow_groups, buffer); packstr(part_ptr->allow_alloc_nodes, buffer); packstr(part_ptr->alternate, buffer); packstr(part_ptr->nodes, buffer); pack_bit_fmt(part_ptr->node_bitmap, buffer); } else if (protocol_version >= SLURM_2_4_PROTOCOL_VERSION) { if (default_part_loc == part_ptr) part_ptr->flags |= PART_FLAG_DEFAULT; else part_ptr->flags &= (~PART_FLAG_DEFAULT); packstr(part_ptr->name, buffer); pack32(part_ptr->grace_time, buffer); pack32(part_ptr->max_time, buffer); pack32(part_ptr->default_time, buffer); pack32(part_ptr->max_nodes_orig, buffer); pack32(part_ptr->min_nodes_orig, buffer); altered = part_ptr->total_nodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &altered); pack32(altered, buffer); pack32(part_ptr->total_cpus, buffer); pack32(part_ptr->def_mem_per_cpu, buffer); pack32(part_ptr->max_mem_per_cpu, buffer); pack16(part_ptr->flags, buffer); pack16(part_ptr->max_share, buffer); pack16(part_ptr->preempt_mode, buffer); pack16(part_ptr->priority, buffer); pack16(part_ptr->state_up, buffer); packstr(part_ptr->allow_groups, buffer); packstr(part_ptr->allow_alloc_nodes, buffer); packstr(part_ptr->alternate, buffer); packstr(part_ptr->nodes, buffer); pack_bit_fmt(part_ptr->node_bitmap, buffer); } else { error("pack_part: protocol_version " "%hu not supported", protocol_version); } }
/* * update_part - create or update a partition's configuration data * IN part_desc - description of partition changes * IN create_flag - create a new partition * RET 0 or an error code * global: part_list - list of partition entries * last_part_update - update time of partition records */ extern int update_part (update_part_msg_t * part_desc, bool create_flag) { int error_code; struct part_record *part_ptr; if (part_desc->name == NULL) { info("update_part: invalid partition name, NULL"); return ESLURM_INVALID_PARTITION_NAME; } error_code = SLURM_SUCCESS; part_ptr = list_find_first(part_list, &list_find_part, part_desc->name); if (create_flag) { if (part_ptr) { verbose("Duplicate partition name for create (%s)", part_desc->name); return ESLURM_INVALID_PARTITION_NAME; } info("update_part: partition %s being created", part_desc->name); part_ptr = create_part_record(); xfree(part_ptr->name); part_ptr->name = xstrdup(part_desc->name); } else { if (!part_ptr) { verbose("Update for partition not found (%s)", part_desc->name); return ESLURM_INVALID_PARTITION_NAME; } } last_part_update = time(NULL); if (part_desc->max_cpus_per_node != NO_VAL) { info("update_part: setting MaxCPUsPerNode to %u for partition %s", part_desc->max_cpus_per_node, part_desc->name); part_ptr->max_cpus_per_node = part_desc->max_cpus_per_node; } if (part_desc->max_time != NO_VAL) { info("update_part: setting max_time to %u for partition %s", part_desc->max_time, part_desc->name); part_ptr->max_time = part_desc->max_time; } if ((part_desc->default_time != NO_VAL) && (part_desc->default_time > part_ptr->max_time)) { info("update_part: DefaultTime would exceed MaxTime for " "partition %s", part_desc->name); } else if (part_desc->default_time != NO_VAL) { info("update_part: setting default_time to %u " "for partition %s", part_desc->default_time, part_desc->name); part_ptr->default_time = part_desc->default_time; } if (part_desc->max_nodes != NO_VAL) { info("update_part: setting max_nodes to %u for partition %s", part_desc->max_nodes, part_desc->name); part_ptr->max_nodes = part_desc->max_nodes; part_ptr->max_nodes_orig = part_desc->max_nodes; select_g_alter_node_cnt(SELECT_SET_MP_CNT, &part_ptr->max_nodes); } if (part_desc->min_nodes != NO_VAL) { info("update_part: setting min_nodes to %u for partition %s", part_desc->min_nodes, part_desc->name); part_ptr->min_nodes = part_desc->min_nodes; part_ptr->min_nodes_orig = part_desc->min_nodes; select_g_alter_node_cnt(SELECT_SET_MP_CNT, &part_ptr->min_nodes); } if (part_desc->grace_time != NO_VAL) { info("update_part: setting grace_time to %u for partition %s", part_desc->grace_time, part_desc->name); part_ptr->grace_time = part_desc->grace_time; } if (part_desc->flags & PART_FLAG_HIDDEN) { info("update_part: setting hidden for partition %s", part_desc->name); part_ptr->flags |= PART_FLAG_HIDDEN; } else if (part_desc->flags & PART_FLAG_HIDDEN_CLR) { info("update_part: clearing hidden for partition %s", part_desc->name); part_ptr->flags &= (~PART_FLAG_HIDDEN); } if (part_desc->flags & PART_FLAG_REQ_RESV) { info("update_part: setting req_resv for partition %s", part_desc->name); part_ptr->flags |= PART_FLAG_REQ_RESV; } else if (part_desc->flags & PART_FLAG_REQ_RESV_CLR) { info("update_part: clearing req_resv for partition %s", part_desc->name); part_ptr->flags &= (~PART_FLAG_REQ_RESV); } if (part_desc->flags & PART_FLAG_ROOT_ONLY) { info("update_part: setting root_only for partition %s", part_desc->name); part_ptr->flags |= PART_FLAG_ROOT_ONLY; } else if (part_desc->flags & PART_FLAG_ROOT_ONLY_CLR) { info("update_part: clearing root_only for partition %s", part_desc->name); part_ptr->flags &= (~PART_FLAG_ROOT_ONLY); } if (part_desc->flags & PART_FLAG_NO_ROOT) { info("update_part: setting no_root for partition %s", part_desc->name); part_ptr->flags |= PART_FLAG_NO_ROOT; } else if (part_desc->flags & PART_FLAG_NO_ROOT_CLR) { info("update_part: clearing no_root for partition %s", part_desc->name); part_ptr->flags &= (~PART_FLAG_NO_ROOT); } if (part_desc->flags & PART_FLAG_DEFAULT) { if (default_part_name == NULL) { info("update_part: setting default partition to %s", part_desc->name); } else if (strcmp(default_part_name, part_desc->name) != 0) { info("update_part: changing default " "partition from %s to %s", default_part_name, part_desc->name); } xfree(default_part_name); default_part_name = xstrdup(part_desc->name); default_part_loc = part_ptr; part_ptr->flags |= PART_FLAG_DEFAULT; } else if ((part_desc->flags & PART_FLAG_DEFAULT_CLR) && (default_part_loc == part_ptr)) { info("update_part: clearing default partition from %s", part_desc->name); xfree(default_part_name); default_part_loc = NULL; part_ptr->flags &= (~PART_FLAG_DEFAULT); } if (part_desc->state_up != (uint16_t) NO_VAL) { info("update_part: setting state_up to %u for partition %s", part_desc->state_up, part_desc->name); part_ptr->state_up = part_desc->state_up; } if (part_desc->max_share != (uint16_t) NO_VAL) { uint16_t force = part_desc->max_share & SHARED_FORCE; uint16_t val = part_desc->max_share & (~SHARED_FORCE); char tmp_str[24]; if (val == 0) snprintf(tmp_str, sizeof(tmp_str), "EXCLUSIVE"); else if (force) snprintf(tmp_str, sizeof(tmp_str), "FORCE:%u", val); else if (val == 1) snprintf(tmp_str, sizeof(tmp_str), "NO"); else snprintf(tmp_str, sizeof(tmp_str), "YES:%u", val); info("update_part: setting share to %s for partition %s", tmp_str, part_desc->name); part_ptr->max_share = part_desc->max_share; } if (part_desc->preempt_mode != (uint16_t) NO_VAL) { uint16_t new_mode; new_mode = part_desc->preempt_mode & (~PREEMPT_MODE_GANG); if (new_mode <= PREEMPT_MODE_CANCEL) { info("update_part: setting preempt_mode to %s for " "partition %s", preempt_mode_string(new_mode), part_desc->name); part_ptr->preempt_mode = new_mode; } else { info("update_part: invalid preempt_mode %u", new_mode); } } if (part_desc->priority != (uint16_t) NO_VAL) { info("update_part: setting priority to %u for partition %s", part_desc->priority, part_desc->name); part_ptr->priority = part_desc->priority; /* If the max_priority changes we need to change all * the normalized priorities of all the other * partitions. If not then just set this partition. */ if (part_ptr->priority > part_max_priority) { ListIterator itr = list_iterator_create(part_list); struct part_record *part2 = NULL; part_max_priority = part_ptr->priority; while((part2 = list_next(itr))) { part2->norm_priority = (double)part2->priority / (double)part_max_priority; } list_iterator_destroy(itr); } else { part_ptr->norm_priority = (double)part_ptr->priority / (double)part_max_priority; } } if (part_desc->allow_groups != NULL) { xfree(part_ptr->allow_groups); xfree(part_ptr->allow_uids); if ((strcasecmp(part_desc->allow_groups, "ALL") == 0) || (part_desc->allow_groups[0] == '\0')) { info("update_part: setting allow_groups to ALL for " "partition %s", part_desc->name); } else { part_ptr->allow_groups = part_desc->allow_groups; part_desc->allow_groups = NULL; info("update_part: setting allow_groups to %s for " "partition %s", part_ptr->allow_groups, part_desc->name); part_ptr->allow_uids = _get_groups_members(part_ptr->allow_groups); clear_group_cache(); } } if (part_desc->allow_alloc_nodes != NULL) { xfree(part_ptr->allow_alloc_nodes); if ((part_desc->allow_alloc_nodes[0] == '\0') || (strcasecmp(part_desc->allow_alloc_nodes, "ALL") == 0)) { part_ptr->allow_alloc_nodes = NULL; info("update_part: setting allow_alloc_nodes to ALL" " for partition %s",part_desc->name); } else { part_ptr->allow_alloc_nodes = part_desc-> allow_alloc_nodes; part_desc->allow_alloc_nodes = NULL; info("update_part: setting allow_alloc_nodes to %s for " "partition %s", part_ptr->allow_alloc_nodes, part_desc->name); } } if (part_desc->alternate != NULL) { xfree(part_ptr->alternate); if ((strcasecmp(part_desc->alternate, "NONE") == 0) || (part_desc->alternate[0] == '\0')) part_ptr->alternate = NULL; else part_ptr->alternate = xstrdup(part_desc->alternate); part_desc->alternate = NULL; info("update_part: setting alternate to %s for " "partition %s", part_ptr->alternate, part_desc->name); } if (part_desc->def_mem_per_cpu != NO_VAL) { char *key; uint32_t value; if (part_desc->def_mem_per_cpu & MEM_PER_CPU) { key = "DefMemPerCpu"; value = part_desc->def_mem_per_cpu & (~MEM_PER_CPU); } else { key = "DefMemPerNode"; value = part_desc->def_mem_per_cpu; } info("update_part: setting %s to %u for partition %s", key, value, part_desc->name); part_ptr->def_mem_per_cpu = part_desc->def_mem_per_cpu; } if (part_desc->max_mem_per_cpu != NO_VAL) { char *key; uint32_t value; if (part_desc->max_mem_per_cpu & MEM_PER_CPU) { key = "MaxMemPerCpu"; value = part_desc->max_mem_per_cpu & (~MEM_PER_CPU); } else { key = "MaxMemPerNode"; value = part_desc->max_mem_per_cpu; } info("update_part: setting %s to %u for partition %s", key, value, part_desc->name); part_ptr->max_mem_per_cpu = part_desc->max_mem_per_cpu; } if (part_desc->nodes != NULL) { char *backup_node_list = part_ptr->nodes; if (part_desc->nodes[0] == '\0') part_ptr->nodes = NULL; /* avoid empty string */ else { int i; part_ptr->nodes = xstrdup(part_desc->nodes); for (i=0; part_ptr->nodes[i]; i++) { if (isspace(part_ptr->nodes[i])) part_ptr->nodes[i] = ','; } } error_code = _build_part_bitmap(part_ptr); if (error_code) { xfree(part_ptr->nodes); part_ptr->nodes = backup_node_list; } else { info("update_part: setting nodes to %s " "for partition %s", part_ptr->nodes, part_desc->name); xfree(backup_node_list); } update_part_nodes_in_resv(part_ptr); } else if (part_ptr->node_bitmap == NULL) { /* Newly created partition needs a bitmap, even if empty */ part_ptr->node_bitmap = bit_alloc(node_record_count); } if (error_code == SLURM_SUCCESS) { slurm_sched_partition_change(); /* notify sched plugin */ select_g_reconfigure(); /* notify select plugin too */ } return error_code; }
static int _job_modify(uint32_t jobid, char *bank_ptr, char *depend_ptr, char *new_hostlist, uint32_t new_node_cnt, char *part_name_ptr, uint32_t new_time_limit, char *name_ptr, char *start_ptr, char *feature_ptr, char *env_ptr, char *comment_ptr, char *gres_ptr, char *wckey_ptr) { struct job_record *job_ptr; time_t now = time(NULL); bool update_accounting = false; job_ptr = find_job_record(jobid); if (job_ptr == NULL) { error("wiki: MODIFYJOB has invalid jobid %u", jobid); return ESLURM_INVALID_JOB_ID; } if (IS_JOB_FINISHED(job_ptr) || (job_ptr->details == NULL)) { info("wiki: MODIFYJOB jobid %u is finished", jobid); return ESLURM_DISABLED; } if (comment_ptr) { info("wiki: change job %u comment %s", jobid, comment_ptr); xfree(job_ptr->comment); job_ptr->comment = xstrdup(comment_ptr); last_job_update = now; } if (depend_ptr) { int rc = update_job_dependency(job_ptr, depend_ptr); if (rc == SLURM_SUCCESS) { info("wiki: changed job %u dependency to %s", jobid, depend_ptr); } else { error("wiki: changing job %u dependency to %s", jobid, depend_ptr); return EINVAL; } } if (env_ptr) { bool have_equal = false; char old_sep[1]; int begin = 0, i; if (job_ptr->batch_flag == 0) { error("wiki: attempt to set environment variables " "for non-batch job %u", jobid); return ESLURM_DISABLED; } for (i=0; ; i++) { if (env_ptr[i] == '=') { if (have_equal) { error("wiki: setting job %u invalid " "environment variables: %s", jobid, env_ptr); return EINVAL; } have_equal = true; if (env_ptr[i+1] == '\"') { for (i+=2; ; i++) { if (env_ptr[i] == '\0') { error("wiki: setting job %u " "invalid environment " "variables: %s", jobid, env_ptr); return EINVAL; } if (env_ptr[i] == '\"') { i++; break; } if (env_ptr[i] == '\\') { i++; } } } else if (env_ptr[i+1] == '\'') { for (i+=2; ; i++) { if (env_ptr[i] == '\0') { error("wiki: setting job %u " "invalid environment " "variables: %s", jobid, env_ptr); return EINVAL; } if (env_ptr[i] == '\'') { i++; break; } if (env_ptr[i] == '\\') { i++; } } } } if (isspace(env_ptr[i]) || (env_ptr[i] == ',')) { if (!have_equal) { error("wiki: setting job %u invalid " "environment variables: %s", jobid, env_ptr); return EINVAL; } old_sep[0] = env_ptr[i]; env_ptr[i] = '\0'; xrealloc(job_ptr->details->env_sup, sizeof(char *) * (job_ptr->details->env_cnt+1)); job_ptr->details->env_sup [job_ptr->details->env_cnt++] = xstrdup(&env_ptr[begin]); info("wiki: for job %u add env: %s", jobid, &env_ptr[begin]); env_ptr[i] = old_sep[0]; if (isspace(old_sep[0])) break; begin = i + 1; have_equal = false; } } } if (new_time_limit) { time_t old_time = job_ptr->time_limit; job_ptr->time_limit = new_time_limit; info("wiki: change job %u time_limit to %u", jobid, new_time_limit); /* Update end_time based upon change * to preserve suspend time info */ job_ptr->end_time = job_ptr->end_time + ((job_ptr->time_limit - old_time) * 60); last_job_update = now; } if (bank_ptr && (update_job_account("wiki", job_ptr, bank_ptr) != SLURM_SUCCESS)) { return EINVAL; } if (feature_ptr) { if (IS_JOB_PENDING(job_ptr) && (job_ptr->details)) { info("wiki: change job %u features to %s", jobid, feature_ptr); job_ptr->details->features = xstrdup(feature_ptr); last_job_update = now; } else { error("wiki: MODIFYJOB features of non-pending " "job %u", jobid); return ESLURM_DISABLED; } } if (start_ptr) { char *end_ptr; uint32_t begin_time = strtol(start_ptr, &end_ptr, 10); if (IS_JOB_PENDING(job_ptr) && (job_ptr->details)) { info("wiki: change job %u begin time to %u", jobid, begin_time); job_ptr->details->begin_time = begin_time; last_job_update = now; update_accounting = true; } else { error("wiki: MODIFYJOB begin_time of non-pending " "job %u", jobid); return ESLURM_DISABLED; } } if (name_ptr) { if (IS_JOB_PENDING(job_ptr)) { info("wiki: change job %u name %s", jobid, name_ptr); xfree(job_ptr->name); job_ptr->name = xstrdup(name_ptr); last_job_update = now; update_accounting = true; } else { error("wiki: MODIFYJOB name of non-pending job %u", jobid); return ESLURM_DISABLED; } } if (new_hostlist) { int rc = 0, task_cnt; hostlist_t hl; char *tasklist; if (!IS_JOB_PENDING(job_ptr) || !job_ptr->details) { /* Job is done, nothing to reset */ if (new_hostlist == '\0') goto host_fini; error("wiki: MODIFYJOB hostlist of non-pending " "job %u", jobid); return ESLURM_DISABLED; } xfree(job_ptr->details->req_nodes); FREE_NULL_BITMAP(job_ptr->details->req_node_bitmap); if (new_hostlist == '\0') goto host_fini; tasklist = moab2slurm_task_list(new_hostlist, &task_cnt); if (tasklist == NULL) { rc = 1; goto host_fini; } hl = hostlist_create(tasklist); if (hl == 0) { rc = 1; goto host_fini; } hostlist_uniq(hl); hostlist_sort(hl); job_ptr->details->req_nodes = hostlist_ranged_string_xmalloc(hl); hostlist_destroy(hl); if (job_ptr->details->req_nodes == NULL) { rc = 1; goto host_fini; } if (node_name2bitmap(job_ptr->details->req_nodes, false, &job_ptr->details->req_node_bitmap)) { rc = 1; goto host_fini; } host_fini: if (rc) { info("wiki: change job %u invalid hostlist %s", jobid, new_hostlist); xfree(job_ptr->details->req_nodes); return EINVAL; } else { info("wiki: change job %u hostlist %s", jobid, new_hostlist); update_accounting = true; } } if (part_name_ptr) { struct part_record *part_ptr; if (!IS_JOB_PENDING(job_ptr)) { error("wiki: MODIFYJOB partition of non-pending " "job %u", jobid); return ESLURM_DISABLED; } part_ptr = find_part_record(part_name_ptr); if (part_ptr == NULL) { error("wiki: MODIFYJOB has invalid partition %s", part_name_ptr); return ESLURM_INVALID_PARTITION_NAME; } info("wiki: change job %u partition %s", jobid, part_name_ptr); xfree(job_ptr->partition); job_ptr->partition = xstrdup(part_name_ptr); job_ptr->part_ptr = part_ptr; last_job_update = now; update_accounting = true; } if (new_node_cnt) { job_desc_msg_t job_desc; #ifdef HAVE_BG uint16_t geometry[SYSTEM_DIMENSIONS] = {(uint16_t) NO_VAL}; static uint16_t cpus_per_node = 0; if (!cpus_per_node) { select_g_alter_node_cnt(SELECT_GET_NODE_CPU_CNT, &cpus_per_node); } #endif if(!IS_JOB_PENDING(job_ptr) || !job_ptr->details) { error("wiki: MODIFYJOB node count of non-pending " "job %u", jobid); return ESLURM_DISABLED; } memset(&job_desc, 0, sizeof(job_desc_msg_t)); job_desc.min_nodes = new_node_cnt; job_desc.max_nodes = NO_VAL; job_desc.select_jobinfo = select_g_select_jobinfo_alloc(); select_g_alter_node_cnt(SELECT_SET_NODE_CNT, &job_desc); select_g_select_jobinfo_free(job_desc.select_jobinfo); job_ptr->details->min_nodes = job_desc.min_nodes; if (job_ptr->details->max_nodes && (job_ptr->details->max_nodes < job_desc.min_nodes)) job_ptr->details->max_nodes = job_desc.min_nodes; info("wiki: change job %u min_nodes to %u", jobid, new_node_cnt); #ifdef HAVE_BG job_ptr->details->min_cpus = job_desc.min_cpus; job_ptr->details->max_cpus = job_desc.max_cpus; job_ptr->details->pn_min_cpus = job_desc.pn_min_cpus; new_node_cnt = job_ptr->details->min_cpus; if (cpus_per_node) new_node_cnt /= cpus_per_node; /* This is only set up so accounting is set up correctly */ select_g_select_jobinfo_set(job_ptr->select_jobinfo, SELECT_JOBDATA_NODE_CNT, &new_node_cnt); /* reset geo since changing this makes any geo potentially invalid */ select_g_select_jobinfo_set(job_ptr->select_jobinfo, SELECT_JOBDATA_GEOMETRY, geometry); #endif last_job_update = now; update_accounting = true; } if (gres_ptr) { char *orig_gres; if (!IS_JOB_PENDING(job_ptr)) { error("wiki: MODIFYJOB GRES of non-pending job %u", jobid); return ESLURM_DISABLED; } orig_gres = job_ptr->gres; job_ptr->gres = NULL; if (gres_ptr[0]) job_ptr->gres = xstrdup(gres_ptr); if (gres_plugin_job_state_validate(job_ptr->gres, &job_ptr->gres_list)) { error("wiki: MODIFYJOB Invalid GRES=%s", gres_ptr); xfree(job_ptr->gres); job_ptr->gres = orig_gres; return ESLURM_INVALID_GRES; } xfree(orig_gres); } if (wckey_ptr) { int rc = update_job_wckey("update_job", job_ptr, wckey_ptr); if (rc != SLURM_SUCCESS) { error("wiki: MODIFYJOB Invalid WCKEY=%s", wckey_ptr); return rc; } } if (update_accounting) { if (job_ptr->details && job_ptr->details->begin_time) { /* Update job record in accounting to reflect * the changes */ jobacct_storage_g_job_start(acct_db_conn, job_ptr); } } return SLURM_SUCCESS; }
/* * pack_part - dump all configuration information about a specific partition * in machine independent form (for network transmission) * IN part_ptr - pointer to partition for which information is requested * IN/OUT buffer - buffer in which data is placed, pointers automatically * updated * global: default_part_loc - pointer to the default partition * NOTE: if you make any changes here be sure to make the corresponding changes * to _unpack_partition_info_members() in common/slurm_protocol_pack.c */ void pack_part(struct part_record *part_ptr, Buf buffer, uint16_t protocol_version) { uint32_t altered; if (protocol_version >= SLURM_2_3_PROTOCOL_VERSION) { if (default_part_loc == part_ptr) part_ptr->flags |= PART_FLAG_DEFAULT; else part_ptr->flags &= (~PART_FLAG_DEFAULT); packstr(part_ptr->name, buffer); pack32(part_ptr->grace_time, buffer); pack32(part_ptr->max_time, buffer); pack32(part_ptr->default_time, buffer); pack32(part_ptr->max_nodes_orig, buffer); pack32(part_ptr->min_nodes_orig, buffer); altered = part_ptr->total_nodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &altered); pack32(altered, buffer); pack32(part_ptr->total_cpus, buffer); pack32(part_ptr->def_mem_per_cpu, buffer); pack32(part_ptr->max_mem_per_cpu, buffer); pack16(part_ptr->flags, buffer); pack16(part_ptr->max_share, buffer); pack16(part_ptr->preempt_mode, buffer); pack16(part_ptr->priority, buffer); pack16(part_ptr->state_up, buffer); packstr(part_ptr->allow_groups, buffer); packstr(part_ptr->allow_alloc_nodes, buffer); packstr(part_ptr->alternate, buffer); packstr(part_ptr->nodes, buffer); pack_bit_fmt(part_ptr->node_bitmap, buffer); } else if (protocol_version >= SLURM_2_2_PROTOCOL_VERSION) { if (default_part_loc == part_ptr) part_ptr->flags |= PART_FLAG_DEFAULT; else part_ptr->flags &= (~PART_FLAG_DEFAULT); packstr(part_ptr->name, buffer); pack32(part_ptr->max_time, buffer); pack32(part_ptr->default_time, buffer); pack32(part_ptr->max_nodes_orig, buffer); pack32(part_ptr->min_nodes_orig, buffer); altered = part_ptr->total_nodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &altered); pack32(altered, buffer); pack32(part_ptr->total_cpus, buffer); pack16(part_ptr->flags, buffer); pack16(part_ptr->max_share, buffer); pack16(part_ptr->preempt_mode, buffer); pack16(part_ptr->priority, buffer); pack16(part_ptr->state_up, buffer); packstr(part_ptr->allow_groups, buffer); packstr(part_ptr->allow_alloc_nodes, buffer); packstr(part_ptr->alternate, buffer); packstr(part_ptr->nodes, buffer); pack_bit_fmt(part_ptr->node_bitmap, buffer); } else { uint16_t default_part_flag, hidden, no_root, root_only, state; if (default_part_loc == part_ptr) default_part_flag = 1; else default_part_flag = 0; if (part_ptr->flags & PART_FLAG_HIDDEN) hidden = 1; else hidden = 0; if (part_ptr->flags & PART_FLAG_NO_ROOT) no_root = 1; else no_root = 0; if (part_ptr->flags & PART_FLAG_ROOT_ONLY) root_only = 1; else root_only = 0; packstr(part_ptr->name, buffer); pack32(part_ptr->max_time, buffer); pack32(part_ptr->default_time, buffer); pack32(part_ptr->max_nodes_orig, buffer); pack32(part_ptr->min_nodes_orig, buffer); altered = part_ptr->total_nodes; select_g_alter_node_cnt(SELECT_APPLY_NODE_MAX_OFFSET, &altered); pack32(altered, buffer); pack32(part_ptr->total_cpus, buffer); pack16(default_part_flag, buffer); pack16(no_root, buffer); pack16(hidden, buffer); pack16(root_only, buffer); pack16(part_ptr->max_share, buffer); pack16(part_ptr->priority, buffer); if (part_ptr->state_up == PARTITION_UP) state = 1; else /* DOWN, DRAIN, and INACTIVE */ state = 0; pack16(state, buffer); packstr(part_ptr->allow_groups, buffer); packstr(part_ptr->allow_alloc_nodes, buffer); packstr(part_ptr->nodes, buffer); pack_bit_fmt(part_ptr->node_bitmap, buffer); } }