Exemplo n.º 1
0
extern int
scontrol_parse_part_options (int argc, char **argv, int *update_cnt_ptr,
			     update_part_msg_t *part_msg_ptr)
{
	int i, min, max;
	char *tag, *val;
	int taglen, vallen;

	if (!update_cnt_ptr) {
		error("scontrol_parse_part_options internal error, "
		      "update_cnt_ptr == NULL");
		exit_code = 1;
		return SLURM_ERROR;
	}
	if (!part_msg_ptr) {
		error("scontrol_parse_part_options internal error, "
		      "part_msg_ptr == NULL");
		exit_code = 1;
		return SLURM_ERROR;
	}

	for (i = 0; i < argc; i++) {
		tag = argv[i];
		val = strchr(argv[i], '=');
		if (val) {
			taglen = val - argv[i];
			val++;
			vallen = strlen(val);
		} else {
			exit_code = 1;
			error("Invalid input: %s  Request aborted", argv[i]);
			return SLURM_ERROR;
		}

		if (xstrncasecmp(tag, "PartitionName", MAX(taglen, 2)) == 0) {
			part_msg_ptr->name = val;
			(*update_cnt_ptr)++;
		} else if (xstrncasecmp(tag, "MaxTime", MAX(taglen, 4)) == 0) {
			int max_time = time_str2mins(val);
			if ((max_time < 0) && (max_time != INFINITE)) {
				exit_code = 1;
				error("Invalid input %s", argv[i]);
				return SLURM_ERROR;
			}
			part_msg_ptr->max_time = max_time;
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "CpuBind", MAX(taglen, 7)) == 0) {
			if (xlate_cpu_bind_str(val, &part_msg_ptr->cpu_bind) !=
			    SLURM_SUCCESS) {
				exit_code = 1;
				error("Invalid input %s", argv[i]);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "DefaultTime", MAX(taglen, 8)) == 0){
			int default_time = time_str2mins(val);
			if ((default_time < 0) && (default_time != INFINITE)) {
				exit_code = 1;
				error("Invalid input %s", argv[i]);
				return SLURM_ERROR;
			}
			part_msg_ptr->default_time = default_time;
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "MaxCPUsPerNode",
				      MAX(taglen, 4)) == 0) {
			if ((xstrcasecmp(val,"UNLIMITED") == 0) ||
			    (xstrcasecmp(val,"INFINITE") == 0)) {
				part_msg_ptr->max_cpus_per_node = INFINITE;
			} else if (parse_uint32(val, &part_msg_ptr->
						      max_cpus_per_node)) {
				error("Invalid MaxCPUsPerNode value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "MaxNodes", MAX(taglen, 4)) == 0) {
			if ((xstrcasecmp(val,"UNLIMITED") == 0) ||
			    (xstrcasecmp(val,"INFINITE") == 0))
				part_msg_ptr->max_nodes = INFINITE;
			else {
				min = 1;
				get_resource_arg_range(val,
					"MaxNodes", &min, &max, true);
				part_msg_ptr->max_nodes = min;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "MinNodes", MAX(taglen, 2)) == 0) {
			min = 1;
			verify_node_count(val, &min, &max);
			part_msg_ptr->min_nodes = min;
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "Default", MAX(taglen, 7)) == 0) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_DEFAULT_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_DEFAULT;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable Default values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "DisableRootJobs", MAX(taglen, 1))) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_NO_ROOT_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_NO_ROOT;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable DisableRootJobs values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "ExclusiveUser", MAX(taglen, 1))) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_EXC_USER_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_EXCLUSIVE_USER;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable ExclusiveUser values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "Hidden", MAX(taglen, 1)) == 0) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_HIDDEN_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_HIDDEN;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable Hidden values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "LLN", MAX(taglen, 1)) == 0) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_LLN_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_LLN;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable LLN values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "RootOnly", MAX(taglen, 3)) == 0) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_ROOT_ONLY_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_ROOT_ONLY;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable RootOnly values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "ReqResv", MAX(taglen, 3)) == 0) {
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_REQ_RESV_CLR;
			else if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0)
				part_msg_ptr->flags |= PART_FLAG_REQ_RESV;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable ReqResv values "
					"are YES and NO");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "OverSubscribe", MAX(taglen, 5)) ||
			 !xstrncasecmp(tag, "Shared", MAX(taglen, 2))) {
			char *colon_pos = strchr(val, ':');
			if (colon_pos) {
				*colon_pos = '\0';
				vallen = strlen(val);
			}
			if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) {
				part_msg_ptr->max_share = 1;

			} else if (xstrncasecmp(val, "EXCLUSIVE",
				   MAX(vallen, 1)) == 0) {
				part_msg_ptr->max_share = 0;

			} else if (xstrncasecmp(val, "YES", MAX(vallen, 1))
				   == 0) {
				if (colon_pos) {
					part_msg_ptr->max_share =
						(uint16_t) strtol(colon_pos+1,
							(char **) NULL, 10);
				} else {
					part_msg_ptr->max_share = (uint16_t) 4;
				}
			} else if (xstrncasecmp(val, "FORCE", MAX(vallen, 1))
				   == 0) {
				if (colon_pos) {
					part_msg_ptr->max_share =
						(uint16_t) strtol(colon_pos+1,
							(char **) NULL, 10) |
							SHARED_FORCE;
				} else {
					part_msg_ptr->max_share =
						(uint16_t) 4 |SHARED_FORCE;
				}
			} else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable OverSubscribe values are "
					"NO, EXCLUSIVE, YES:#, and FORCE:#");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "OverTimeLimit", MAX(taglen, 5))
			  == 0) {
			if ((xstrcasecmp(val,"UNLIMITED") == 0) ||
			    (xstrcasecmp(val,"INFINITE") == 0)) {
				part_msg_ptr->over_time_limit =
					INFINITE16;
			} else if (parse_uint16(val, &part_msg_ptr->
						      over_time_limit)) {
				error("Invalid OverTimeLimit value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (xstrncasecmp(tag, "PreemptMode", MAX(taglen, 3)) == 0) {
			uint16_t new_mode = preempt_mode_num(val);
			if (new_mode != NO_VAL16)
				part_msg_ptr->preempt_mode = new_mode;
			else {
				error("Invalid input: %s", argv[i]);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "Priority", MAX(taglen, 3))) {
			if (parse_uint16(val, &part_msg_ptr->priority_tier)) {
				error("Invalid Priority value: %s", val);
				return SLURM_ERROR;
			}
			part_msg_ptr->priority_job_factor =
				part_msg_ptr->priority_tier;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag,"PriorityJobFactor",MAX(taglen, 3))) {
			if (parse_uint16(val,
					 &part_msg_ptr->priority_job_factor)) {
				error("Invalid PriorityJobFactor value: %s",
				      val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "PriorityTier", MAX(taglen, 3))) {
			if (parse_uint16(val, &part_msg_ptr->priority_tier)) {
				error("Invalid PriorityTier value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "State", MAX(taglen, 2))) {
			if (!xstrncasecmp(val, "INACTIVE", MAX(vallen, 1)))
				part_msg_ptr->state_up = PARTITION_INACTIVE;
			else if (!xstrncasecmp(val, "DOWN", MAX(vallen, 1)))
				part_msg_ptr->state_up = PARTITION_DOWN;
			else if (!xstrncasecmp(val, "UP", MAX(vallen, 1)))
				part_msg_ptr->state_up = PARTITION_UP;
			else if (!xstrncasecmp(val, "DRAIN", MAX(vallen, 1)))
				part_msg_ptr->state_up = PARTITION_DRAIN;
			else {
				exit_code = 1;
				error("Invalid input: %s", argv[i]);
				error("Acceptable State values "
					"are UP, DOWN, DRAIN and INACTIVE");
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "Nodes", MAX(taglen, 1))) {
			part_msg_ptr->nodes = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "AllowGroups", MAX(taglen, 6))) {
			part_msg_ptr->allow_groups = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "AllowAccounts", MAX(taglen, 6))) {
			part_msg_ptr->allow_accounts = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "AllowQos", MAX(taglen, 6))) {
			part_msg_ptr->allow_qos = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "DenyAccounts", MAX(taglen, 5))) {
			part_msg_ptr->deny_accounts = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "DenyQos", MAX(taglen, 5))) {
			part_msg_ptr->deny_qos = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "AllocNodes", MAX(taglen, 6))) {
			part_msg_ptr->allow_alloc_nodes = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "Alternate", MAX(taglen, 3))) {
			part_msg_ptr->alternate = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "GraceTime", MAX(taglen, 5))) {
			if (parse_uint32(val, &part_msg_ptr->grace_time)) {
				error ("Invalid GraceTime value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "DefMemPerCPU", MAX(taglen, 10))) {
			if (parse_uint64(val, &part_msg_ptr->def_mem_per_cpu)) {
				error ("Invalid DefMemPerCPU value: %s", val);
				return SLURM_ERROR;
			}
			part_msg_ptr->def_mem_per_cpu |= MEM_PER_CPU;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "DefMemPerNode", MAX(taglen, 10))) {
			if (parse_uint64(val, &part_msg_ptr->def_mem_per_cpu)) {
				error ("Invalid DefMemPerNode value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "MaxMemPerCPU", MAX(taglen, 10))) {
			if (parse_uint64(val, &part_msg_ptr->max_mem_per_cpu)) {
				error ("Invalid MaxMemPerCPU value: %s", val);
				return SLURM_ERROR;
			}
			part_msg_ptr->max_mem_per_cpu |= MEM_PER_CPU;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "MaxMemPerNode", MAX(taglen, 10))) {
			if (parse_uint64(val, &part_msg_ptr->max_mem_per_cpu)) {
				error ("Invalid MaxMemPerNode value: %s", val);
				return SLURM_ERROR;
			}
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "QoS", MAX(taglen, 3))) {
			part_msg_ptr->qos_char = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "JobDefaults", MAX(taglen, 4))) {
			part_msg_ptr->job_defaults_str = val;
			(*update_cnt_ptr)++;
		}
		else if (!xstrncasecmp(tag, "TresBillingWeights",
				       MAX(taglen, 1))) {
			part_msg_ptr->billing_weights_str = val;
			(*update_cnt_ptr)++;
		}
		else {
			exit_code = 1;
			error("Update of this parameter is not "
			      "supported: %s\n", argv[i]);
			error("Request aborted");
			return SLURM_ERROR;
		}
	}
	return SLURM_SUCCESS;
}
Exemplo n.º 2
0
/*
 * scontrol_update_node - update the slurm node configuration per the supplied
 *	arguments
 * IN argc - count of arguments
 * IN argv - list of arguments
 * RET 0 if no slurm error, errno otherwise. parsing error prints
 *			error message and returns 0
 */
extern int
scontrol_update_node (int argc, char **argv)
{
	int i, j, rc = 0, update_cnt = 0;
	uint16_t state_val;
	update_node_msg_t node_msg;
	char *reason_str = NULL;
	char *tag, *val;
	int tag_len, val_len;

	slurm_init_update_node_msg(&node_msg);
	for (i = 0; i < argc; i++) {
		tag = argv[i];
		val = strchr(argv[i], '=');
		if (val) {
			tag_len = val - argv[i];
			val++;
			val_len = strlen(val);
		} else {
			exit_code = 1;
			error("Invalid input: %s  Request aborted", argv[i]);
			return -1;
		}

		if (xstrncasecmp(tag, "NodeAddr", MAX(tag_len, 5)) == 0) {
			node_msg.node_addr = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "NodeHostName", MAX(tag_len, 5))
			   == 0) {
			node_msg.node_hostname = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "NodeName", MAX(tag_len, 1)) == 0) {
			node_msg.node_names = val;
		} else if (!xstrncasecmp(tag, "ActiveFeatures",
					 MAX(tag_len,3))) {
			node_msg.features_act = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "CpuBind", MAX(tag_len, 7)) == 0) {
			if (xlate_cpu_bind_str(val, &node_msg.cpu_bind) !=
			    SLURM_SUCCESS) {
				exit_code = 1;
				error("Invalid input %s", argv[i]);
				return -1;
			}
			update_cnt++;


		} else if (!xstrncasecmp(tag, "Features", MAX(tag_len, 1)) ||
			   !xstrncasecmp(tag, "AvailableFeatures",
					 MAX(tag_len,3))) {
			node_msg.features = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Gres", MAX(tag_len, 1)) == 0) {
			node_msg.gres = val;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Weight", MAX(tag_len,1)) == 0) {
			/* Logic borrowed from function _handle_uint32 */
			char *endptr;
			unsigned long num;
			errno = 0;
			num = strtoul(val, &endptr, 0);
			if ((endptr[0] == 'k') || (endptr[0] == 'K')) {
				num *= 1024;
				endptr++;
			}
			if ((num == 0 && errno == EINVAL)
        		            || (*endptr != '\0')) {
				if ((xstrcasecmp(val, "UNLIMITED") == 0) ||
				    (xstrcasecmp(val, "INFINITE")  == 0)) {
					num = INFINITE;
				} else {
					error("Weight value (%s) is not a "
					      "valid number", val);
					break;
				}
			} else if (errno == ERANGE) {
				error("Weight value (%s) is out of range",
				      val);
				break;
			} else if (val[0] == '-') {
				error("Weight value (%s) is less than zero",
				      val);
				break;
			} else if (num > 0xfffffff0) {
				error("Weight value (%s) is greater than %u",
					val, 0xfffffff0);
				break;
			}
			node_msg.weight = num;
			update_cnt++;
		} else if (xstrncasecmp(tag, "Reason", MAX(tag_len, 1)) == 0) {
			int len = strlen(val);
			reason_str = xmalloc(len+1);
			if (*val == '"')
				strcpy(reason_str, val+1);
			else
				strcpy(reason_str, val);

			len = strlen(reason_str) - 1;
			if ((len >= 0) && (reason_str[len] == '"'))
				reason_str[len] = '\0';

			node_msg.reason = reason_str;
			if ((getlogin() == NULL) ||
			    (uid_from_string(getlogin(),
					     &node_msg.reason_uid) < 0)) {
				node_msg.reason_uid = getuid();
			}
			update_cnt++;
		}
		else if (xstrncasecmp(tag, "State", MAX(tag_len, 1)) == 0) {
			if (cluster_flags & CLUSTER_FLAG_CRAY_A) {
				fprintf (stderr, "%s can not be changed through"
					 " SLURM. Use native Cray tools such as"
					 " xtprocadmin(8)\n", argv[i]);
				fprintf (stderr, "Request aborted\n");
				exit_code = 1;
				goto done;
			}
			if (xstrncasecmp(val, "NoResp",
				        MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_NO_RESPOND;
				update_cnt++;
			} else if (xstrncasecmp(val, "DRAIN",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_DRAIN;
				update_cnt++;
			} else if (xstrncasecmp(val, "FAIL",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_FAIL;
				update_cnt++;
			} else if (xstrncasecmp(val, "FUTURE",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_FUTURE;
				update_cnt++;
			} else if (xstrncasecmp(val, "RESUME",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_RESUME;
				update_cnt++;
			} else if (xstrncasecmp(val, "POWER_DOWN",
				   MAX(val_len, 7)) == 0) {
				node_msg.node_state = NODE_STATE_POWER_SAVE;
				update_cnt++;
			} else if (xstrncasecmp(val, "POWER_UP",
				   MAX(val_len, 7)) == 0) {
				node_msg.node_state = NODE_STATE_POWER_UP;
				update_cnt++;
			} else if (xstrncasecmp(val, "UNDRAIN",
				   MAX(val_len, 3)) == 0) {
				node_msg.node_state = NODE_STATE_UNDRAIN;
				update_cnt++;
			} else {
				state_val = NO_VAL16;
				for (j = 0; j < NODE_STATE_END; j++) {
					if (xstrncasecmp(node_state_string(j),
							 val,
							 MAX(val_len, 3)) == 0){
						state_val = (uint16_t) j;
						break;
					}
				}
				if (j == NODE_STATE_END) {
					exit_code = 1;
					fprintf(stderr, "Invalid input: %s\n",
						argv[i]);
					fprintf (stderr, "Request aborted\n");
					fprintf (stderr, "Valid states are: ");
					fprintf (stderr,
						 "NoResp DRAIN FAIL FUTURE RESUME "
						 "POWER_DOWN POWER_UP UNDRAIN");
					fprintf (stderr, "\n");
					fprintf (stderr,
						 "Not all states are valid "
						 "given a node's prior "
						 "state\n");
					goto done;
				}
				node_msg.node_state = state_val;
				update_cnt++;
			}
		} else {
			exit_code = 1;
			fprintf (stderr, "Update of this parameter is not "
				 "supported: %s\n", argv[i]);
			fprintf (stderr, "Request aborted\n");
			goto done;
		}
	}

	if (((node_msg.node_state == NODE_STATE_DOWN)  ||
	     (node_msg.node_state == NODE_STATE_DRAIN) ||
	     (node_msg.node_state == NODE_STATE_FAIL)) &&
	    ((node_msg.reason == NULL) || (strlen(node_msg.reason) == 0))) {
		fprintf(stderr, "You must specify a reason when DOWNING or "
			"DRAINING a node. Request denied\n");
		goto done;
	}

	if (update_cnt == 0) {
		exit_code = 1;
		fprintf (stderr, "No changes specified\n");
		return 0;
	}

	rc = slurm_update_node(&node_msg);

done:	xfree(reason_str);
	if (rc) {
		exit_code = 1;
		return slurm_get_errno ();
	} else
		return 0;
}