Ejemplo n.º 1
0
static int _parse_resv_tres(char *val, resv_desc_msg_t  *resv_msg_ptr,
                            int *free_tres_license, int *free_tres_bb,
                            int *free_tres_corecnt, int *free_tres_nodecnt)
{
    int i, ret, len;
    char *tres_bb = NULL, *tres_license = NULL,
          *tres_corecnt = NULL, *tres_nodecnt = NULL,
           *token, *type = NULL, *saveptr1 = NULL,
                    *value_str = NULL, *name = NULL, *compound = NULL,
                     *tmp = NULL;
    bool discard, first;

    *free_tres_license = 0;
    *free_tres_bb = 0;
    *free_tres_corecnt = 0;
    *free_tres_nodecnt = 0;

    token = strtok_r(val, ",", &saveptr1);
    while (token) {

        compound = strtok_r(token, "=", &value_str);

        if (!value_str || !*value_str) {
            error("TRES component '%s' has an invalid value '%s'",
                  type, token);
            goto error;
        }

        if (strchr(compound, '/')) {
            tmp = xstrdup(compound);
            type = strtok_r(tmp, "/", &name);
        } else
            type = compound;

        if (_is_configured_tres(compound) < 0)
            goto error;

        if (!strcasecmp(type, "license")) {
            if (tres_license && tres_license[0] != '\0')
                xstrcatchar(tres_license, ',');
            xstrfmtcat(tres_license, "%s:%s", name, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
            if (tmp)
                xfree(tmp);

        } else if (strcasecmp(type, "bb") == 0) {
            if (tres_bb && tres_bb[0] != '\0')
                xstrcatchar(tres_bb, ',');
            xstrfmtcat(tres_bb, "%s:%s", name, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
            if (tmp)
                xfree(tmp);

        } else if (strcasecmp(type, "cpu") == 0) {
            first = true;
            discard = false;
            do {
                len = strlen(value_str);
                for (i = 0; i < len; i++) {
                    if (!isdigit(value_str[i])) {
                        if (first) {
                            error("TRES value '%s' "
                                  "is invalid",
                                  value_str);
                            goto error;
                        } else
                            discard = true;
                        break;
                    }
                }
                first = false;
                if (!discard) {
                    if (tres_corecnt && tres_corecnt[0]
                            != '\0')
                        xstrcatchar(tres_corecnt, ',');
                    xstrcat(tres_corecnt, value_str);

                    token = strtok_r(NULL, ",", &saveptr1);
                    value_str = token;
                }
            } while (!discard && token);

        } else if (strcasecmp(type, "node") == 0) {
            if (tres_nodecnt && tres_nodecnt[0] != '\0')
                xstrcatchar(tres_nodecnt, ',');
            xstrcat(tres_nodecnt, value_str);
            token = strtok_r(NULL, ",", &saveptr1);
        } else {
            error("TRES type '%s' not supported with reservations",
                  compound);
            goto error;
        }

    }

    if (tres_corecnt && tres_corecnt[0] != '\0') {
        ret = _parse_resv_core_cnt(resv_msg_ptr, tres_corecnt, true);
        xfree(tres_corecnt);
        if (ret != SLURM_SUCCESS)
            goto error;
        *free_tres_corecnt = 1;
    }

    if (tres_nodecnt && tres_nodecnt[0] != '\0') {
        ret = _parse_resv_node_cnt(resv_msg_ptr, tres_nodecnt, true);
        xfree(tres_nodecnt);
        if (ret != SLURM_SUCCESS)
            goto error;
        *free_tres_nodecnt = 1;
    }

    if (tres_license && tres_license[0] != '\0') {
        resv_msg_ptr->licenses = tres_license;
        *free_tres_license = 1;
    }

    if (tres_bb && tres_bb[0] != '\0') {
        resv_msg_ptr->burst_buffer = tres_bb;
        *free_tres_bb = 1;
    }

    return SLURM_SUCCESS;

error:
    xfree(tres_nodecnt);
    xfree(tres_corecnt);
    exit_code = 1;
    return SLURM_ERROR;
}
Ejemplo n.º 2
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 *free_tres_license, int *free_tres_bb,
                           int *free_tres_corecnt, int *free_tres_nodecnt)
{
    int i;
    int duration = -3;   /* -1 == INFINITE, -2 == error, -3 == not set */

    *free_user_str = 0;
    *free_acct_str = 0;
    *free_tres_license = 0;
    *free_tres_bb = 0;
    *free_tres_corecnt = 0;
    *free_tres_nodecnt = 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 SLURM_ERROR;
        }
        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 SLURM_ERROR;
            }
            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 SLURM_ERROR;
            }
            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 SLURM_ERROR;
            }
            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 SLURM_ERROR;
            } else {
                resv_msg_ptr->flags = f;
            }
        } else if (strncasecmp(tag, "NodeCnt", MAX(taglen,5)) == 0 ||
                   strncasecmp(tag, "NodeCount", MAX(taglen,5)) == 0) {

            if (_parse_resv_node_cnt(resv_msg_ptr, val, false)
                    == SLURM_ERROR)
                return SLURM_ERROR;

        } 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) {

            if (_parse_resv_core_cnt(resv_msg_ptr, val, false)
                    == SLURM_ERROR)
                return SLURM_ERROR;

        } 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, "TRES", MAX(taglen, 1)) == 0) {
            if (_parse_resv_tres(val, resv_msg_ptr,
                                 free_tres_license, free_tres_bb,
                                 free_tres_corecnt,
                                 free_tres_nodecnt) == SLURM_ERROR)
                return SLURM_ERROR;

        } 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 SLURM_ERROR;
            }
        } else if (strncasecmp(tag, "res", 3) == 0) {
            continue;
        } else {
            exit_code = 1;
            error("Unknown parameter %s.  %s", argv[i], msg);
            return SLURM_ERROR;
        }
    }

    return SLURM_SUCCESS;
}
Ejemplo n.º 3
0
/* don't free this char */
static const char *_set_resv_msg(resv_desc_msg_t *resv_msg,
				 const char *new_text,
				 int column)
{
	char *type = "", *temp_str;
	char *tmp_text, *last = NULL, *tok;
	int block_inx, temp_int = 0;
	uint32_t f;

	/* need to clear global_edit_error here (just in case) */
	global_edit_error = 0;
	if (global_edit_error_msg)
		g_free(global_edit_error_msg);

	if (!resv_msg)
		return NULL;

	switch (column) {
	case SORTID_ACCOUNTS:
		resv_msg->accounts = xstrdup(new_text);
		type = "accounts";
		break;
	case SORTID_ACTION:
		xfree(got_edit_signal);
		if (!xstrcasecmp(new_text, "None"))
			got_edit_signal = NULL;
		else
			got_edit_signal = xstrdup(new_text);
		break;
	case SORTID_BURST_BUFFER:
		resv_msg->burst_buffer = xstrdup(new_text);
		type = "burst_buffer";
		break;
        case SORTID_CORE_CNT:
		if (cluster_flags & CLUSTER_FLAG_BG)
			type = "Cnode Count";
		else
			type = "Core Count";
                if (_parse_resv_core_cnt(resv_msg, new_text) == SLURM_ERROR) {
			global_edit_error_msg = g_strdup_printf(
				"Can't use %s when system "
				"is not running cons_res select plugin", type);
			goto return_error;
                }
                break;
	case SORTID_DURATION:
		temp_int = time_str2mins((char *)new_text);
		if (temp_int <= 0)
			goto return_error;
		resv_msg->duration = temp_int;
		type = "duration";
		break;
	case SORTID_TIME_END:
		resv_msg->end_time = parse_time((char *)new_text, 0);
		type = "end time";
		break;
	case SORTID_FEATURES:
		resv_msg->features = xstrdup(new_text);
		type = "features";
		break;
	case SORTID_FLAGS:
		f = parse_resv_flags(new_text, __func__);
		type = "flags";
		if (f == (uint32_t)NO_VAL)
			goto return_error;
		resv_msg->flags = f;
		break;
	case SORTID_LICENSES:
		resv_msg->licenses = xstrdup(new_text);
		type = "licenses";
		break;
	case SORTID_NAME:
		resv_msg->name = xstrdup(new_text);
		type = "name";
		break;
	case SORTID_NODE_CNT:
		if (cluster_flags & CLUSTER_FLAG_BG)
			type = "Midplane Count";
		else
			type = "Node Count";
		block_inx = 0;
		tmp_text = xstrdup(new_text);
		tok = strtok_r(tmp_text, ",", &last);
		while (tok) {
			temp_int = strtol(tok, &temp_str, 10);
			if ((temp_str[0] == 'k') || (temp_str[0] == 'k'))
				temp_int *= 1024;
			if ((temp_str[0] == 'm') || (temp_str[0] == 'm'))
				temp_int *= (1024 * 1024);
			xrealloc(resv_msg->node_cnt,
				 (sizeof(uint32_t) * (block_inx + 2)));
			resv_msg->node_cnt[block_inx++] = temp_int;
			if (temp_int <= 0) {
				xfree(tmp_text);
				xfree(resv_msg->node_cnt);
				goto return_error;
			}
			tok = strtok_r(NULL, ",", &last);
		}
		xfree(tmp_text);
		break;
	case SORTID_NODELIST:
		resv_msg->node_list = xstrdup(new_text);
		if (cluster_flags & CLUSTER_FLAG_BG)
			type = "Midplane List";
		else
			type = "Node List";
		break;
	case SORTID_PARTITION:
		resv_msg->partition = xstrdup(new_text);
		type = "partition";
		break;
	case SORTID_TIME_START:
		resv_msg->start_time = parse_time((char *)new_text, 0);
		type = "start time";
		break;
	case SORTID_USERS:
		resv_msg->users = xstrdup(new_text);
		type = "users";
		break;
	case SORTID_WATTS:
		resv_msg->resv_watts = _parse_watts((char *) new_text);
		type = "watts";
		break;
	default:
		type = "unknown";
		break;
	}

	if (xstrcmp(type, "unknown"))
		global_send_update_msg = 1;

	return type;

return_error:
	global_edit_error = 1;
	return type;
}