提交 51907779 编写于 作者: P Peter Krempa

virsh: Update only changed scheduler tunables

When setting the cpu tunables in virsh you are able to update only a
subset of them. Virsh while doing the update updated all of the
tunables, changed ones with new values and unchanged with old ones.
This is unfortunate as it:
a) might overwrite some other change by a race condition (unprobable)
b) fails with range checking as some of the old values saved might be
   out of range

This patch changes the update procedure so that only the changed value
is updated on the host.

This patch also fixes a very unprobable memory leak if the daemon would
return a string tunable parameter, as the typed parameter array was not
cleared.
上级 245cef9f
...@@ -3277,95 +3277,79 @@ static const vshCmdOptDef opts_schedinfo[] = { ...@@ -3277,95 +3277,79 @@ static const vshCmdOptDef opts_schedinfo[] = {
static int static int
cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd, cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd,
virTypedParameterPtr param) virTypedParameterPtr src_params, int nsrc_params,
virTypedParameterPtr *update_params)
{ {
const char *data = NULL; const char *set_arg;
char *set_field = NULL;
/* Legacy 'weight' parameter */ char *set_val = NULL;
if (STREQ(param->field, "weight") &&
param->type == VIR_TYPED_PARAM_UINT && virTypedParameterPtr param;
vshCommandOptBool(cmd, "weight")) { virTypedParameterPtr params = NULL;
int val; int nparams = 0;
if (vshCommandOptInt(cmd, "weight", &val) <= 0) { size_t params_size = 0;
vshError(ctl, "%s", _("Invalid value of weight")); int ret = -1;
return -1; int rv;
} else { int val;
param->value.ui = val; int i;
if (vshCommandOptString(cmd, "set", &set_arg) > 0) {
set_field = vshStrdup(ctl, set_arg);
if (!(set_val = strchr(set_field, '='))) {
vshError(ctl, "%s", _("Invalid syntax for --set, expecting name=value"));
goto cleanup;
} }
return 1;
*set_val = '\0';
set_val++;
} }
/* Legacy 'cap' parameter */ for (i = 0; i < nsrc_params; i++) {
if (STREQ(param->field, "cap") && param = &(src_params[i]);
param->type == VIR_TYPED_PARAM_UINT && if (VIR_RESIZE_N(params, params_size, nparams, 1) < 0) {
vshCommandOptBool(cmd, "cap")) { virReportOOMError();
int val; goto cleanup;
if (vshCommandOptInt(cmd, "cap", &val) <= 0) {
vshError(ctl, "%s", _("Invalid value of cap"));
return -1;
} else {
param->value.ui = val;
} }
return 1;
}
if (vshCommandOptString(cmd, "set", &data) > 0) { /* Legacy 'weight' and 'cap' parameter */
char *val = strchr(data, '='); if (param->type == VIR_TYPED_PARAM_UINT &&
int match = 0; (STREQ(param->field, "weight") || STREQ(param->field, "cap")) &&
if (!val) { (rv = vshCommandOptInt(cmd, param->field, &val)) != 0) {
vshError(ctl, "%s", _("Invalid syntax for --set, expecting name=value")); if (rv < 0) {
return -1; vshError(ctl, _("Invalid value of %s"), param->field);
goto cleanup;
}
if (virTypedParameterAssign(&(params[nparams++]),
param->field,
param->type,
val) < 0)
goto cleanup;
continue;
} }
*val = '\0';
match = STREQ(data, param->field);
*val = '=';
val++;
if (!match)
return 0;
switch (param->type) { if (set_field && STREQ(set_field, param->field)) {
case VIR_TYPED_PARAM_INT: if (virTypedParameterAssignFromStr(&(params[nparams++]),
if (virStrToLong_i(val, NULL, 10, &param->value.i) < 0) { param->field,
vshError(ctl, "%s", param->type,
_("Invalid value for parameter, expecting an int")); set_val) < 0)
return -1; goto cleanup;
}
break; continue;
case VIR_TYPED_PARAM_UINT:
if (virStrToLong_ui(val, NULL, 10, &param->value.ui) < 0) {
vshError(ctl, "%s",
_("Invalid value for parameter, expecting an unsigned int"));
return -1;
}
break;
case VIR_TYPED_PARAM_LLONG:
if (virStrToLong_ll(val, NULL, 10, &param->value.l) < 0) {
vshError(ctl, "%s",
_("Invalid value for parameter, expecting a long long"));
return -1;
}
break;
case VIR_TYPED_PARAM_ULLONG:
if (virStrToLong_ull(val, NULL, 10, &param->value.ul) < 0) {
vshError(ctl, "%s",
_("Invalid value for parameter, expecting an unsigned long long"));
return -1;
}
break;
case VIR_TYPED_PARAM_DOUBLE:
if (virStrToDouble(val, NULL, &param->value.d) < 0) {
vshError(ctl, "%s", _("Invalid value for parameter, expecting a double"));
return -1;
}
break;
case VIR_TYPED_PARAM_BOOLEAN:
param->value.b = STREQ(val, "0") ? 0 : 1;
} }
return 1;
} }
return 0; *update_params = params;
ret = nparams;
params = NULL;
cleanup:
VIR_FREE(set_field);
virTypedParameterArrayClear(params, nparams);
VIR_FREE(params);
return ret;
} }
static bool static bool
...@@ -3374,8 +3358,9 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) ...@@ -3374,8 +3358,9 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
char *schedulertype; char *schedulertype;
virDomainPtr dom; virDomainPtr dom;
virTypedParameterPtr params = NULL; virTypedParameterPtr params = NULL;
virTypedParameterPtr updates = NULL;
int nparams = 0; int nparams = 0;
int update = 0; int nupdates = 0;
int i, ret; int i, ret;
bool ret_val = false; bool ret_val = false;
unsigned int flags = 0; unsigned int flags = 0;
...@@ -3429,22 +3414,18 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) ...@@ -3429,22 +3414,18 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
goto cleanup; goto cleanup;
/* See if any params are being set */ /* See if any params are being set */
for (i = 0; i < nparams; i++) { if ((nupdates = cmdSchedInfoUpdate(ctl, cmd, params, nparams,
ret = cmdSchedInfoUpdate(ctl, cmd, &(params[i])); &updates)) < 0)
if (ret == -1) goto cleanup;
goto cleanup;
if (ret == 1)
update = 1;
}
/* Update parameters & refresh data */ /* Update parameters & refresh data */
if (update) { if (nupdates > 0) {
if (flags || current) if (flags || current)
ret = virDomainSetSchedulerParametersFlags(dom, params, ret = virDomainSetSchedulerParametersFlags(dom, updates,
nparams, flags); nupdates, flags);
else else
ret = virDomainSetSchedulerParameters(dom, params, nparams); ret = virDomainSetSchedulerParameters(dom, updates, nupdates);
if (ret == -1) if (ret == -1)
goto cleanup; goto cleanup;
...@@ -3484,7 +3465,10 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) ...@@ -3484,7 +3465,10 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
} }
cleanup: cleanup:
virTypedParameterArrayClear(params, nparams);
virTypedParameterArrayClear(updates, nupdates);
VIR_FREE(params); VIR_FREE(params);
VIR_FREE(updates);
virDomainFree(dom); virDomainFree(dom);
return ret_val; return ret_val;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册