* @nparams: pointer to number of memory parameters; input and output
* @flags: extra flags; not used yet, so callers should always pass 0
*
- * Get all node memory parameters. On input, @nparams gives the size
- * of the @params array; on output, @nparams gives how many slots were
- * filled with parameter information, which might be less but will
- * not exceed the input value.
+ * Get all node memory parameters (parameters unsupported by OS will be
+ * omitted). On input, @nparams gives the size of the @params array;
+ * on output, @nparams gives how many slots were filled with parameter
+ * information, which might be less but will not exceed the input value.
*
* As a special case, calling with @params as NULL and @nparams as 0 on
* input will cause @nparams on output to contain the number of parameters
* value nparams of virDomainGetSchedulerType)
* @flags: extra flags; not used yet, so callers should always pass 0
*
- * Change all or a subset of the node memory tunables.
+ * Change all or a subset of the node memory tunables. The function
+ * fails if not all of the tunables are supported.
*
* Note that it's not recommended to use this function while the
* outside tuning program is running (such as ksmtuned under Linux),
#ifdef __linux__
static int
-nodeSetMemoryParameterValue(const char *field,
- virTypedParameterPtr param)
+nodeSetMemoryParameterValue(virTypedParameterPtr param)
{
char *path = NULL;
char *strval = NULL;
int ret = -1;
int rc = -1;
+ char *field = strchr(param->field, '_');
+ field++;
if (virAsprintf(&path, "%s/%s",
SYSFS_MEMORY_SHARED_PATH, field) < 0) {
virReportOOMError();
}
if ((rc = virFileWriteStr(path, strval, 0)) < 0) {
- virReportSystemError(-rc, _("failed to set %s"), field);
+ virReportSystemError(-rc, _("failed to set %s"), param->field);
goto cleanup;
}
VIR_FREE(strval);
return ret;
}
+
+static bool
+nodeMemoryParametersIsAllSupported(virTypedParameterPtr params,
+ int nparams)
+{
+ char *path = NULL;
+ int i;
+
+ for (i = 0; i < nparams; i++) {
+ virTypedParameterPtr param = ¶ms[i];
+
+ char *field = strchr(param->field, '_');
+ field++;
+ if (virAsprintf(&path, "%s/%s",
+ SYSFS_MEMORY_SHARED_PATH, field) < 0) {
+ virReportOOMError();
+ return false;
+ }
+
+ if (!virFileExists(path)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("Parameter '%s' is not supported by "
+ "this kernel"), param->field);
+ VIR_FREE(path);
+ return false;
+ }
+
+ VIR_FREE(path);
+ }
+
+ return true;
+}
#endif
int
virCheckFlags(0, -1);
#ifdef __linux__
- int ret = 0;
int i;
+ int rc;
if (virTypedParameterArrayValidate(params, nparams,
VIR_NODE_MEMORY_SHARED_PAGES_TO_SCAN,
NULL) < 0)
return -1;
- for (i = 0; i < nparams; i++) {
- virTypedParameterPtr param = ¶ms[i];
-
- if (STREQ(param->field,
- VIR_NODE_MEMORY_SHARED_PAGES_TO_SCAN)) {
- ret = nodeSetMemoryParameterValue("pages_to_scan", param);
-
- /* Out of memory */
- if (ret == -2)
- return -1;
- } else if (STREQ(param->field,
- VIR_NODE_MEMORY_SHARED_SLEEP_MILLISECS)) {
- ret = nodeSetMemoryParameterValue("sleep_millisecs", param);
+ if (!nodeMemoryParametersIsAllSupported(params, nparams))
+ return -1;
- /* Out of memory */
- if (ret == -2)
- return -1;
- } else if (STREQ(param->field,
- VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES)) {
- ret = nodeSetMemoryParameterValue("merge_across_nodes", param);
+ for (i = 0; i < nparams; i++) {
+ rc = nodeSetMemoryParameterValue(¶ms[i]);
- /* Out of memory */
- if (ret == -2)
- return -1;
- }
+ /* Out of memory */
+ if (rc == -2)
+ return -1;
}
- return ret;
+ return 0;
#else
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("node set memory parameters not implemented"
goto cleanup;
}
+ if (!virFileExists(path)) {
+ ret = -2;
+ goto cleanup;
+ }
+
if (virFileReadAll(path, 1024, &buf) < 0)
goto cleanup;
unsigned long long pages_volatile;
unsigned long long full_scans = 0;
int i;
+ int ret;
if ((*nparams) == 0) {
*nparams = NODE_MEMORY_PARAMETERS_NUM;
switch (i) {
case 0:
- if (nodeGetMemoryParameterValue("pages_to_scan",
- &pages_to_scan) < 0)
+ ret = nodeGetMemoryParameterValue("pages_to_scan", &pages_to_scan);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_PAGES_TO_SCAN,
break;
case 1:
- if (nodeGetMemoryParameterValue("sleep_millisecs",
- &sleep_millisecs) < 0)
+ ret = nodeGetMemoryParameterValue("sleep_millisecs", &sleep_millisecs);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_SLEEP_MILLISECS,
break;
case 2:
- if (nodeGetMemoryParameterValue("pages_shared",
- &pages_shared) < 0)
+ ret = nodeGetMemoryParameterValue("pages_shared", &pages_shared);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_PAGES_SHARED,
break;
case 3:
- if (nodeGetMemoryParameterValue("pages_sharing",
- &pages_sharing) < 0)
+ ret = nodeGetMemoryParameterValue("pages_sharing", &pages_sharing);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_PAGES_SHARING,
break;
case 4:
- if (nodeGetMemoryParameterValue("pages_unshared",
- &pages_unshared) < 0)
+ ret = nodeGetMemoryParameterValue("pages_unshared", &pages_unshared);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_PAGES_UNSHARED,
break;
case 5:
- if (nodeGetMemoryParameterValue("pages_volatile",
- &pages_volatile) < 0)
+ ret = nodeGetMemoryParameterValue("pages_volatile", &pages_volatile);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_PAGES_VOLATILE,
break;
case 6:
- if (nodeGetMemoryParameterValue("full_scans",
- &full_scans) < 0)
+ ret = nodeGetMemoryParameterValue("full_scans", &full_scans);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_FULL_SCANS,
break;
case 7:
- if (nodeGetMemoryParameterValue("merge_across_nodes",
- &merge_across_nodes) < 0)
+ ret = nodeGetMemoryParameterValue("merge_across_nodes", &merge_across_nodes);
+ if (ret == -2)
+ continue;
+ else if (ret == -1)
return -1;
if (virTypedParameterAssign(param, VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES,