mirror of https://gitee.com/openkylin/libvirt.git
virsh: Rework parseRateStr
The function is used to parse a tuple delimited by commas into virNetDevBandwidth structure. So far only three out of fore fields are supported: average, peak and burst. The single missing field is floor. Well, the parsing works, but I think we can do better. Especially when we will need to parse floor too in very close future. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
5ee6d243fc
commit
6983d6d2c3
|
@ -865,36 +865,58 @@ static const vshCmdOptDef opts_attach_interface[] = {
|
||||||
/* parse inbound and outbound which are in the format of
|
/* parse inbound and outbound which are in the format of
|
||||||
* 'average,peak,burst', in which peak and burst are optional,
|
* 'average,peak,burst', in which peak and burst are optional,
|
||||||
* thus 'average,,burst' and 'average,peak' are also legal. */
|
* thus 'average,,burst' and 'average,peak' are also legal. */
|
||||||
static int parseRateStr(const char *rateStr, virNetDevBandwidthRatePtr rate)
|
static int parseRateStr(vshControl *ctl,
|
||||||
|
const char *rateStr,
|
||||||
|
virNetDevBandwidthRatePtr rate)
|
||||||
{
|
{
|
||||||
const char *average = NULL;
|
char *token;
|
||||||
char *peak = NULL, *burst = NULL;
|
char *next;
|
||||||
|
char *saveptr = NULL;
|
||||||
|
enum {
|
||||||
|
AVERAGE, PEAK, BURST
|
||||||
|
} state;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
average = rateStr;
|
if (!rateStr)
|
||||||
if (!average)
|
|
||||||
return -1;
|
|
||||||
if (virStrToLong_ull(average, &peak, 10, &rate->average) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* peak will be updated to point to the end of rateStr in case
|
next = vshStrdup(ctl, rateStr);
|
||||||
* of 'average' */
|
|
||||||
if (peak && *peak != '\0') {
|
for (state = AVERAGE; state <= BURST; state++) {
|
||||||
burst = strchr(peak + 1, ',');
|
unsigned long long *tmp;
|
||||||
if (!(burst && (burst - peak == 1))) {
|
const char *field_name;
|
||||||
if (virStrToLong_ull(peak + 1, &burst, 10, &rate->peak) < 0)
|
|
||||||
return -1;
|
if (!(token = strtok_r(next, ",", &saveptr)))
|
||||||
|
break;
|
||||||
|
next = NULL;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case AVERAGE:
|
||||||
|
tmp = &rate->average;
|
||||||
|
field_name = "average";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEAK:
|
||||||
|
tmp = &rate->peak;
|
||||||
|
field_name = "peak";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BURST:
|
||||||
|
tmp = &rate->burst;
|
||||||
|
field_name = "burst";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* burst will be updated to point to the end of rateStr in case
|
if (virStrToLong_ullp(token, NULL, 10, tmp) < 0) {
|
||||||
* of 'average,peak' */
|
vshError(ctl, _("malformed %s field"), field_name);
|
||||||
if (burst && *burst != '\0') {
|
goto cleanup;
|
||||||
if (virStrToLong_ull(burst + 1, NULL, 10, &rate->burst) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
return 0;
|
cleanup:
|
||||||
|
VIR_FREE(next);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -952,10 +974,8 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||||
|
|
||||||
if (inboundStr) {
|
if (inboundStr) {
|
||||||
memset(&inbound, 0, sizeof(inbound));
|
memset(&inbound, 0, sizeof(inbound));
|
||||||
if (parseRateStr(inboundStr, &inbound) < 0) {
|
if (parseRateStr(ctl, inboundStr, &inbound) < 0)
|
||||||
vshError(ctl, _("inbound format is incorrect"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
if (inbound.average == 0) {
|
if (inbound.average == 0) {
|
||||||
vshError(ctl, _("inbound average is mandatory"));
|
vshError(ctl, _("inbound average is mandatory"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -963,10 +983,8 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||||
}
|
}
|
||||||
if (outboundStr) {
|
if (outboundStr) {
|
||||||
memset(&outbound, 0, sizeof(outbound));
|
memset(&outbound, 0, sizeof(outbound));
|
||||||
if (parseRateStr(outboundStr, &outbound) < 0) {
|
if (parseRateStr(ctl, outboundStr, &outbound) < 0)
|
||||||
vshError(ctl, _("outbound format is incorrect"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
if (outbound.average == 0) {
|
if (outbound.average == 0) {
|
||||||
vshError(ctl, _("outbound average is mandatory"));
|
vshError(ctl, _("outbound average is mandatory"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -3280,10 +3298,8 @@ cmdDomIftune(vshControl *ctl, const vshCmd *cmd)
|
||||||
memset(&outbound, 0, sizeof(outbound));
|
memset(&outbound, 0, sizeof(outbound));
|
||||||
|
|
||||||
if (inboundStr) {
|
if (inboundStr) {
|
||||||
if (parseRateStr(inboundStr, &inbound) < 0) {
|
if (parseRateStr(ctl, inboundStr, &inbound) < 0)
|
||||||
vshError(ctl, _("inbound format is incorrect"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
/* we parse the rate as unsigned long long, but the API
|
/* we parse the rate as unsigned long long, but the API
|
||||||
* only accepts UINT */
|
* only accepts UINT */
|
||||||
if (inbound.average > UINT_MAX || inbound.peak > UINT_MAX ||
|
if (inbound.average > UINT_MAX || inbound.peak > UINT_MAX ||
|
||||||
|
@ -3316,10 +3332,8 @@ cmdDomIftune(vshControl *ctl, const vshCmd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outboundStr) {
|
if (outboundStr) {
|
||||||
if (parseRateStr(outboundStr, &outbound) < 0) {
|
if (parseRateStr(ctl, outboundStr, &outbound) < 0)
|
||||||
vshError(ctl, _("outbound format is incorrect"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
if (outbound.average > UINT_MAX || outbound.peak > UINT_MAX ||
|
if (outbound.average > UINT_MAX || outbound.peak > UINT_MAX ||
|
||||||
outbound.burst > UINT_MAX) {
|
outbound.burst > UINT_MAX) {
|
||||||
vshError(ctl, _("outbound rate larger than maximum %u"),
|
vshError(ctl, _("outbound rate larger than maximum %u"),
|
||||||
|
|
Loading…
Reference in New Issue