Exemplo n.º 1
0
static char *	_get_node_state(struct node_record *node_ptr)
{
	static bool got_select_type = false;
	static bool node_allocations;

	if (!got_select_type) {
		char * select_type = slurm_get_select_type();
		if (select_type &&
		    (strcasecmp(select_type, "select/linear") == 0))
			node_allocations = true;
		else
			node_allocations = false;
		xfree(select_type);
		got_select_type = true;
	}

	if (IS_NODE_DRAIN(node_ptr) || IS_NODE_FAIL(node_ptr))
		return "Draining";
	if (IS_NODE_COMPLETING(node_ptr))
		return "Busy";

	if (IS_NODE_DOWN(node_ptr))
		return "Down";
	if (IS_NODE_ALLOCATED(node_ptr)) {
		if (node_allocations)
			return "Busy";
		else
			return "Running";
	}
	if (IS_NODE_IDLE(node_ptr))
		return "Idle";

	return "Unknown";
}
Exemplo n.º 2
0
static int _parse_resv_core_cnt(resv_desc_msg_t *resv_msg_ptr, char *val,
                                bool from_tres)
{

    char *endptr = NULL, *core_cnt, *tok, *ptrptr = NULL;
    char *type;
    int node_inx = 0;

    type = slurm_get_select_type();
    if (strcasestr(type, "cray")) {
        int param;
        param = slurm_get_select_type_param();
        if (! (param & CR_OTHER_CONS_RES)) {
            error("CoreCnt or CPUCnt is only "
                  "suported when "
                  "SelectTypeParameters "
                  "includes OTHER_CONS_RES");
            xfree(type);
            return SLURM_ERROR;
        }
    } else if (strcasestr(type, "cons_res") == NULL) {
        error("CoreCnt or CPUCnt is only "
              "suported when "
              "SelectType includes "
              "select/cons_res");
        xfree(type);
        return SLURM_ERROR;
    }

    xfree(type);
    core_cnt = xstrdup(val);
    tok = strtok_r(core_cnt, ",", &ptrptr);
    while (tok) {
        xrealloc(resv_msg_ptr->core_cnt,
                 sizeof(uint32_t) * (node_inx + 2));
        resv_msg_ptr->core_cnt[node_inx] =
            strtol(tok, &endptr, 10);
        if ((endptr == NULL) ||
                (endptr[0] != '\0') ||
                (tok[0] == '\0')) {
            exit_code = 1;
            if (from_tres)
                error("Invalid TRES core count %s", val);
            else
                error("Invalid core count %s", val);
            xfree(core_cnt);
            return SLURM_ERROR;
        }
        node_inx++;
        tok = strtok_r(NULL, ",", &ptrptr);
    }

    xfree(core_cnt);
    return SLURM_SUCCESS;
}
Exemplo n.º 3
0
static void _load_config(void)
{
	char *sched_params, *select_type, *tmp_ptr;

	sched_timeout = slurm_get_msg_timeout() / 2;
	sched_timeout = MAX(sched_timeout, 1);
	sched_timeout = MIN(sched_timeout, 10);

	sched_params = slurm_get_sched_params();

	if (sched_params && (tmp_ptr=strstr(sched_params, "interval=")))
		builtin_interval = atoi(tmp_ptr + 9);
	if (builtin_interval < 1) {
		error("Invalid SchedulerParameters interval: %d",
		      builtin_interval);
		builtin_interval = BACKFILL_INTERVAL;
	}

	if (sched_params && (tmp_ptr=strstr(sched_params, "max_job_bf=")))
		max_sched_job_cnt = atoi(tmp_ptr + 11);
	if (sched_params && (tmp_ptr=strstr(sched_params, "bf_max_job_test=")))
		max_sched_job_cnt = atoi(tmp_ptr + 16);
	if (max_sched_job_cnt < 1) {
		error("Invalid SchedulerParameters bf_max_job_test: %d",
		      max_sched_job_cnt);
		max_sched_job_cnt = 50;
	}
	xfree(sched_params);

	select_type = slurm_get_select_type();
	if (!xstrcmp(select_type, "select/serial")) {
		/* Do not spend time computing expected start time for
		 * pending jobs */
		max_sched_job_cnt = 0;
		stop_builtin_agent();
	}
	xfree(select_type);
}
Exemplo n.º 4
0
/*
 * Initialize context for node selection plugin
 */
extern int slurm_select_init(bool only_default)
{
	int retval = SLURM_SUCCESS;
	char *type = NULL;
	int i, j, len;
	DIR *dirp;
	struct dirent *e;
	char *dir_array = NULL, *head = NULL;
	char *plugin_type = "select";

	if ( init_run && select_context )
		return retval;

	slurm_mutex_lock( &select_context_lock );

	if ( select_context )
		goto done;

	type = slurm_get_select_type();
	if (working_cluster_rec) {
		/* just ignore warnings here */
	} else {
#ifdef HAVE_XCPU
		if (strcasecmp(type, "select/linear")) {
			error("%s is incompatible with XCPU use", type);
			fatal("Use SelectType=select/linear");
		}
#endif
		if (!strcasecmp(type, "select/linear")) {
			uint16_t cr_type = slurm_get_select_type_param();
			if ((cr_type & CR_SOCKET) || (cr_type & CR_CORE) ||
			    (cr_type & CR_CPU))
				fatal("Invalid SelectTypeParameter "
				      "for select/linear");
		}

#ifdef HAVE_BG
		if (strcasecmp(type, "select/bluegene")) {
			error("%s is incompatible with BlueGene", type);
			fatal("Use SelectType=select/bluegene");
		}
#else
		if (!strcasecmp(type, "select/bluegene")) {
			fatal("Requested SelectType=select/bluegene "
			      "in slurm.conf, but not running on a BG[L|P|Q] "
			      "system.  If looking to emulate a BG[L|P|Q] "
			      "system use --enable-bgl-emulation or "
			      "--enable-bgp-emulation respectively.");
		}
#endif

#ifdef HAVE_ALPS_CRAY
		if (strcasecmp(type, "select/alps")) {
			error("%s is incompatible with Cray system "
			      "running alps", type);
			fatal("Use SelectType=select/alps");
		}
#else
		if (!strcasecmp(type, "select/alps")) {
			fatal("Requested SelectType=select/alps "
			      "in slurm.conf, but not running on a ALPS Cray "
			      "system.  If looking to emulate a Alps Cray "
			      "system use --enable-alps-cray-emulation.");
		}
#endif
	}

	select_context_cnt = 0;
	if (only_default) {
		ops = xmalloc(sizeof(slurm_select_ops_t));
		select_context = xmalloc(sizeof(plugin_context_t));
		if ((select_context[0] = plugin_context_create(
			     plugin_type, type, (void **)&ops[0],
			     node_select_syms, sizeof(node_select_syms)))) {
			select_context_default = 0;
			select_context_cnt++;
		}
		goto skip_load_all;
	}

	if (!(dir_array = slurm_get_plugin_dir())) {
		error("plugin_load_and_link: No plugin dir given");
		goto done;
	}

	head = dir_array;
	for (i=0; ; i++) {
		bool got_colon = 0;
		if (dir_array[i] == ':') {
			dir_array[i] = '\0';
			got_colon = 1;
		} else if (dir_array[i] != '\0')
			continue;

		/* Open the directory. */
		if (!(dirp = opendir(head))) {
			error("cannot open plugin directory %s", head);
			goto done;
		}

		while (1) {
			char full_name[128];

			if (!(e = readdir( dirp )))
				break;
			/* Check only files with select_ in them. */
			if (strncmp(e->d_name, "select_", 7))
				continue;

			len = strlen(e->d_name);
#if defined(__CYGWIN__)
			len -= 4;
#else
			len -= 3;
#endif
			/* Check only shared object files */
			if (strcmp(e->d_name+len,
#if defined(__CYGWIN__)
				   ".dll"
#else
				   ".so"
#endif
				    ))
				continue;
			/* add one for the / */
			len++;
			xassert(len<sizeof(full_name));
			snprintf(full_name, len, "select/%s", e->d_name+7);
			for (j=0; j<select_context_cnt; j++) {
				if (!strcmp(full_name,
					    select_context[j]->type))
					break;
			}
			if (j >= select_context_cnt) {
				xrealloc(ops,
					 (sizeof(slurm_select_ops_t) *
					  (select_context_cnt + 1)));
				xrealloc(select_context,
					 (sizeof(plugin_context_t) *
					  (select_context_cnt + 1)));

				select_context[select_context_cnt] =
					plugin_context_create(
						plugin_type, full_name,
						(void **)&ops[
							select_context_cnt],
						node_select_syms,
						sizeof(node_select_syms));
				if (select_context[select_context_cnt]) {
					/* set the default */
					if (!strcmp(full_name, type))
						select_context_default =
							select_context_cnt;
					select_context_cnt++;
				}
			}
		}

		closedir(dirp);

		if (got_colon) {
			head = dir_array + i + 1;
		} else
			break;
	}

skip_load_all:
	if (select_context_default == -1)
		fatal("Can't find plugin for %s", type);

	/* Insure that plugin_id is valid and unique */
	for (i=0; i<select_context_cnt; i++) {
		for (j=i+1; j<select_context_cnt; j++) {
			if (*(ops[i].plugin_id) !=
			    *(ops[j].plugin_id))
				continue;
			fatal("SelectPlugins: Duplicate plugin_id %u for "
			      "%s and %s",
			      *(ops[i].plugin_id),
			      select_context[i]->type,
			      select_context[j]->type);
		}
		if (*(ops[i].plugin_id) < 100) {
			fatal("SelectPlugins: Invalid plugin_id %u (<100) %s",
			      *(ops[i].plugin_id),
			      select_context[i]->type);
		}

	}
	init_run = true;

done:
	slurm_mutex_unlock( &select_context_lock );
	xfree(type);
	xfree(dir_array);
	return retval;
}
Exemplo n.º 5
0
/*
 * Initialize context for node selection plugin
 */
extern int slurm_select_init(bool only_default)
{
	int retval = SLURM_SUCCESS;
	char *select_type = NULL;
	int i, j, rc, len;
	DIR *dirp;
	struct dirent *e;
	char *dir_array = NULL, *head = NULL;

	slurm_mutex_lock( &select_context_lock );

	if ( select_context )
		goto done;

	select_type = slurm_get_select_type();
	if (working_cluster_rec) {
		/* just ignore warnings here */
	} else {
#ifdef HAVE_XCPU
		if (strcasecmp(select_type, "select/linear")) {
			error("%s is incompatible with XCPU use", select_type);
			fatal("Use SelectType=select/linear");
		}
#endif

#ifdef HAVE_BG
		if (strcasecmp(select_type, "select/bluegene")) {
			error("%s is incompatible with BlueGene", select_type);
			fatal("Use SelectType=select/bluegene");
		}
#else
		if (!strcasecmp(select_type, "select/bluegene")) {
			fatal("Requested SelectType=select/bluegene "
			      "in slurm.conf, but not running on a BG[L|P|Q] "
			      "system.  If looking to emulate a BG[L|P|Q] "
			      "system use --enable-bgl-emulation or "
			      "--enable-bgp-emulation respectively.");
		}
#endif

#ifdef HAVE_CRAY
		if (strcasecmp(select_type, "select/cray")) {
			error("%s is incompatible with Cray", select_type);
			fatal("Use SelectType=select/cray");
		}
#else
		if (!strcasecmp(select_type, "select/cray")) {
			fatal("Requested SelectType=select/cray "
			      "in slurm.conf, but not running on a Cray "
			      "system.  If looking to emulate a Cray "
			      "system use --enable-cray-emulation.");
		}
#endif
	}

	select_context_cnt = 0;
	if(only_default) {
		select_context = xmalloc(sizeof(slurm_select_context_t));
		rc = _select_get_ops(select_type, select_context);
		if (rc == SLURM_SUCCESS) {
			select_context_default = 0;
			select_context_cnt++;
		}
		goto skip_load_all;
	}

	if(!(dir_array = slurm_get_plugin_dir())) {
		error("plugin_load_and_link: No plugin dir given");
		goto done;
	}

	head = dir_array;
	for (i=0; ; i++) {
		bool got_colon = 0;
		if (dir_array[i] == ':') {
			dir_array[i] = '\0';
			got_colon = 1;
		} else if(dir_array[i] != '\0')
			continue;

		/* Open the directory. */
		if(!(dirp = opendir(head))) {
			error("cannot open plugin directory %s", head);
			goto done;
		}

		while (1) {
			char full_name[128];

			if(!(e = readdir( dirp )))
				break;
			/* Check only files with select_ in them. */
			if (strncmp(e->d_name, "select_", 7))
				continue;

			len = strlen(e->d_name);
#if defined(__CYGWIN__)
			len -= 4;
#else
			len -= 3;
#endif
			/* Check only shared object files */
			if (strcmp(e->d_name+len,
#if defined(__CYGWIN__)
				   ".dll"
#else
				   ".so"
#endif
				    ))
				continue;
			/* add one for the / */
			len++;
			xassert(len<sizeof(full_name));
			snprintf(full_name, len, "select/%s", e->d_name+7);
			for (j=0; j<select_context_cnt; j++) {
				if (!strcmp(full_name,
					    select_context[j].select_type))
					break;
			}
			if (j < select_context_cnt) {
				error("Duplicate plugin %s ignored",
				      select_context[j].select_type);
			} else {
				xrealloc(select_context,
					 (sizeof(slurm_select_context_t) *
					  (select_context_cnt + 1)));

				rc = _select_get_ops(
					full_name,
					select_context + select_context_cnt);

				/* only add the ones this system has */
				if (rc == SLURM_SUCCESS) {
					/* set the default */
					if (!strcmp(full_name, select_type))
						select_context_default =
							select_context_cnt;
					select_context_cnt++;
				}
			}
		}

		closedir(dirp);

		if (got_colon) {
			head = dir_array + i + 1;
		} else
			break;
	}

skip_load_all:
	if(select_context_default == -1)
		fatal("Can't find plugin for %s", select_type);

	/* Insure that plugin_id is valid and unique */
	for (i=0; i<select_context_cnt; i++) {
		for (j=i+1; j<select_context_cnt; j++) {
			if (*(select_context[i].ops.plugin_id) !=
			    *(select_context[j].ops.plugin_id))
				continue;
			fatal("SelectPlugins: Duplicate plugin_id %u for "
			      "%s and %s",
			      *(select_context[i].ops.plugin_id),
			      select_context[i].select_type,
			      select_context[j].select_type);
		}
		if (*(select_context[i].ops.plugin_id) < 100) {
			fatal("SelectPlugins: Invalid plugin_id %u (<100) %s",
			      *(select_context[i].ops.plugin_id),
			      select_context[i].select_type);
		}

	}

done:
	slurm_mutex_unlock( &select_context_lock );
	xfree(select_type);
	xfree(dir_array);
	return retval;
}
Exemplo n.º 6
0
/*
 * Initialize context for node selection plugin
 */
extern int slurm_select_init(bool only_default)
{
	int retval = SLURM_SUCCESS;
	char *select_type = NULL;
	int i, j, plugin_cnt;
	char *plugin_type = "select";
	List plugin_names = NULL;
	_plugin_args_t plugin_args = {0};

	if ( init_run && select_context )
		return retval;

	slurm_mutex_lock( &select_context_lock );

	if ( select_context )
		goto done;

	select_type = slurm_get_select_type();
	if (working_cluster_rec) {
		/* just ignore warnings here */
	} else {
#ifdef HAVE_NATIVE_CRAY
		if (xstrcasecmp(select_type, "select/cray")) {
			error("%s is incompatible with a native Cray system.",
			      select_type);
			fatal("Use SelectType=select/cray");
		}
#else
		/* if (!xstrcasecmp(select_type, "select/cray")) { */
		/* 	fatal("Requested SelectType=select/cray " */
		/* 	      "in slurm.conf, but not running on a native Cray " */
		/* 	      "system.  If looking to run on a Cray " */
		/* 	      "system natively use --enable-native-cray."); */
		/* } */
#endif
	}

	select_context_cnt = 0;

	plugin_args.plugin_type    = plugin_type;
	plugin_args.default_plugin = select_type;

	if (only_default) {
		plugin_names = list_create(slurm_destroy_char);
		list_append(plugin_names, xstrdup(select_type));
	} else {
		plugin_names = plugin_get_plugins_of_type(plugin_type);
	}
	if (plugin_names && (plugin_cnt = list_count(plugin_names))) {
		ops = xcalloc(plugin_cnt, sizeof(slurm_select_ops_t));
		select_context = xcalloc(plugin_cnt,
					 sizeof(plugin_context_t *));
		list_for_each(plugin_names, _load_plugins, &plugin_args);
	}


	if (select_context_default == -1)
		fatal("Can't find plugin for %s", select_type);

	/* Ensure that plugin_id is valid and unique */
	for (i=0; i<select_context_cnt; i++) {
		for (j=i+1; j<select_context_cnt; j++) {
			if (*(ops[i].plugin_id) !=
			    *(ops[j].plugin_id))
				continue;
			fatal("SelectPlugins: Duplicate plugin_id %u for "
			      "%s and %s",
			      *(ops[i].plugin_id),
			      select_context[i]->type,
			      select_context[j]->type);
		}
		if (*(ops[i].plugin_id) < 100) {
			fatal("SelectPlugins: Invalid plugin_id %u (<100) %s",
			      *(ops[i].plugin_id),
			      select_context[i]->type);
		}

	}
	init_run = true;
done:
	slurm_mutex_unlock( &select_context_lock );
	if (!working_cluster_rec) {
		if (select_running_linear_based()) {
			uint16_t cr_type = slurm_get_select_type_param();
			if (cr_type & (CR_CPU | CR_CORE | CR_SOCKET)) {
				fatal("Invalid SelectTypeParameters for "
				      "%s: %s (%u), it can't contain "
				      "CR_(CPU|CORE|SOCKET).",
				      select_type,
				      select_type_param_string(cr_type),
				      cr_type);
			}
		}
	}

	xfree(select_type);
	FREE_NULL_LIST(plugin_names);

	return retval;
}
Exemplo n.º 7
0
/*
 * scontrol_parse_res_options   parse options for creating or updating a
                                reservation
 * IN argc - count of arguments
 * IN argv - list of arguments
 * IN msg  - a string to append to any error message
 * OUT resv_msg_ptr - struct holding reservation parameters
 * OUT free_user_str - bool indicating that resv_msg_ptr->users should be freed
 * OUT free_acct_str - bool indicating that resv_msg_ptr->accounts should be
 *		       freed
 * RET 0 on success, -1 on err and prints message
 */
extern int
scontrol_parse_res_options(int argc, char *argv[], const char *msg,
			   resv_desc_msg_t  *resv_msg_ptr,
			   int *free_user_str, int *free_acct_str)
{
	int i;
	int duration = -3;   /* -1 == INFINITE, -2 == error, -3 == not set */

	*free_user_str = 0;
	*free_acct_str = 0;

	for (i=0; i<argc; i++) {
		char *tag = argv[i];
		int taglen = 0;
		char plus_minus = '\0';

		char *val = strchr(argv[i], '=');
		taglen = val - argv[i];

		if (!val && strncasecmp(argv[i], "res", 3) == 0) {
			continue;
		} else if (!val || taglen == 0) {
			exit_code = 1;
			error("Unknown parameter %s.  %s", argv[i], msg);
			return -1;
		}
		if (val[-1] == '+' || val[-1] == '-') {
			plus_minus = val[-1];
			taglen--;
		}
		val++;

		if (strncasecmp(tag, "ReservationName", MAX(taglen, 1)) == 0) {
			resv_msg_ptr->name = val;

		} else if (strncasecmp(tag, "Accounts", MAX(taglen, 1)) == 0) {
			if (plus_minus) {
				resv_msg_ptr->accounts =
					_process_plus_minus(plus_minus, val);
				*free_acct_str = 1;
			} else {
				resv_msg_ptr->accounts = val;
			}
		} else if (strncasecmp(tag, "BurstBuffer", MAX(taglen, 2))
			   == 0) {
			resv_msg_ptr->burst_buffer = val;
		} else if (strncasecmp(tag, "StartTime", MAX(taglen, 1)) == 0){
			time_t  t = parse_time(val, 0);
			if (errno == ESLURM_INVALID_TIME_VALUE) {
				exit_code = 1;
				error("Invalid start time %s.  %s",
				      argv[i], msg);
				return -1;
			}
			resv_msg_ptr->start_time = t;

		} else if (strncasecmp(tag, "EndTime", MAX(taglen, 1)) == 0) {
			time_t  t = parse_time(val, 0);
			if (errno == ESLURM_INVALID_TIME_VALUE) {
				exit_code = 1;
				error("Invalid end time %s.  %s", argv[i],msg);
				return -1;
			}
			resv_msg_ptr->end_time = t;

		} else if (strncasecmp(tag, "Duration", MAX(taglen, 1)) == 0) {
			/* -1 == INFINITE, -2 == error, -3 == not set */
			duration = time_str2mins(val);
			if (duration < 0 && duration != INFINITE) {
				exit_code = 1;
				error("Invalid duration %s.  %s", argv[i],msg);
				return -1;
			}
			resv_msg_ptr->duration = (uint32_t)duration;

		} else if (strncasecmp(tag, "Flags", MAX(taglen, 2)) == 0) {
			uint32_t f;
			if (plus_minus) {
				char *tmp =
					_process_plus_minus(plus_minus, val);
				f = parse_resv_flags(tmp, msg);
				xfree(tmp);
			} else {
				f = parse_resv_flags(val, msg);
			}
			if (f == 0xffffffff) {
				return -1;
			} else {
				resv_msg_ptr->flags = f;
			}
		} else if (strncasecmp(tag, "NodeCnt", MAX(taglen,5)) == 0 ||
			   strncasecmp(tag, "NodeCount", MAX(taglen,5)) == 0) {
			char *endptr = NULL, *node_cnt, *tok, *ptrptr = NULL;
			int node_inx = 0;
			node_cnt = xstrdup(val);
			tok = strtok_r(node_cnt, ",", &ptrptr);
			while (tok) {
				xrealloc(resv_msg_ptr->node_cnt,
					 sizeof(uint32_t) * (node_inx + 2));
				resv_msg_ptr->node_cnt[node_inx] =
					strtol(tok, &endptr, 10);
				if ((endptr != NULL) &&
				    ((endptr[0] == 'k') ||
				     (endptr[0] == 'K'))) {
					resv_msg_ptr->node_cnt[node_inx] *=
						1024;
				} else if ((endptr != NULL) &&
					   ((endptr[0] == 'm') ||
					    (endptr[0] == 'M'))) {
					resv_msg_ptr->node_cnt[node_inx] *=
						1024 * 1024;
				} else if ((endptr == NULL) ||
					   (endptr[0] != '\0') ||
					   (tok[0] == '\0')) {
					exit_code = 1;
					error("Invalid node count %s.  %s",
					      argv[i], msg);
					xfree(node_cnt);
					return -1;
				}
				node_inx++;
				tok = strtok_r(NULL, ",", &ptrptr);
			}
			xfree(node_cnt);

		} else if (strncasecmp(tag, "CoreCnt",   MAX(taglen,5)) == 0 ||
		           strncasecmp(tag, "CoreCount", MAX(taglen,5)) == 0 ||
		           strncasecmp(tag, "CPUCnt",    MAX(taglen,5)) == 0 ||
			   strncasecmp(tag, "CPUCount",  MAX(taglen,5)) == 0) {

			char *endptr = NULL, *core_cnt, *tok, *ptrptr = NULL;
			char *type;
			int node_inx = 0;

			type = slurm_get_select_type();
			if (strcasestr(type, "cray")) {
				int param;
				param = slurm_get_select_type_param();
				if (! (param & CR_OTHER_CONS_RES)) {
					error("CoreCnt or CPUCnt is only "
					      "suported when "
					      "SelectTypeParameters "
					      "includes OTHER_CONS_RES");
					xfree(type);
					return -1;
				}
			} else {
				if (strcasestr(type, "cons_res") == NULL) {
					error("CoreCnt or CPUCnt is only "
					      "suported when "
					      "SelectType includes "
					      "select/cons_res");
					xfree(type);
					return -1;
				}
			}
			xfree(type);
			core_cnt = xstrdup(val);
			tok = strtok_r(core_cnt, ",", &ptrptr);
			while (tok) {
				xrealloc(resv_msg_ptr->core_cnt,
					 sizeof(uint32_t) * (node_inx + 2));
				resv_msg_ptr->core_cnt[node_inx] =
					strtol(tok, &endptr, 10);
				if ((endptr == NULL) ||
				   (endptr[0] != '\0') ||
				   (tok[0] == '\0')) {
					exit_code = 1;
					error("Invalid core count %s. %s",
					      argv[i], msg);
					xfree(core_cnt);
					return -1;
				}
				node_inx++;
				tok = strtok_r(NULL, ",", &ptrptr);
			}
			xfree(core_cnt);

		} else if (strncasecmp(tag, "Nodes", MAX(taglen, 5)) == 0) {
			resv_msg_ptr->node_list = val;

		} else if (strncasecmp(tag, "Features", MAX(taglen, 2)) == 0) {
			resv_msg_ptr->features = val;

		} else if (strncasecmp(tag, "Licenses", MAX(taglen, 2)) == 0) {
			resv_msg_ptr->licenses = val;

		} else if (strncasecmp(tag, "PartitionName", MAX(taglen, 1))
			   == 0) {
			resv_msg_ptr->partition = val;

		} else if (strncasecmp(tag, "Users", MAX(taglen, 1)) == 0) {
			if (plus_minus) {
				resv_msg_ptr->users =
					_process_plus_minus(plus_minus, val);
				*free_user_str = 1;
			} else {
				resv_msg_ptr->users = val;
			}
		} else if (strncasecmp(tag, "Watts", MAX(taglen, 1)) == 0) {
			if (parse_uint32(val, &(resv_msg_ptr->resv_watts))) {
				error("Invalid Watts value: %s", val);
				return -1;
			}
		} else if (strncasecmp(tag, "res", 3) == 0) {
			continue;
		} else {
			exit_code = 1;
			error("Unknown parameter %s.  %s", argv[i], msg);
			return -1;
		}
	}
	return 0;
}