mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
virsh: Expose virNodeGetFreePages
The new API is exposed under 'freepages' command. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
34f2d0319d
commit
9e3efe53de
@ -193,6 +193,167 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "freepages" command
|
||||||
|
*/
|
||||||
|
static const vshCmdInfo info_freepages[] = {
|
||||||
|
{.name = "help",
|
||||||
|
.data = N_("NUMA free memory")
|
||||||
|
},
|
||||||
|
{.name = "desc",
|
||||||
|
.data = N_("display available free memory for the NUMA cell.")
|
||||||
|
},
|
||||||
|
{.name = NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vshCmdOptDef opts_freepages[] = {
|
||||||
|
{.name = "cellno",
|
||||||
|
.type = VSH_OT_INT,
|
||||||
|
.help = N_("NUMA cell number")
|
||||||
|
},
|
||||||
|
{.name = "pagesize",
|
||||||
|
.type = VSH_OT_INT,
|
||||||
|
.help = N_("page size (in kibibites)")
|
||||||
|
},
|
||||||
|
{.name = "all",
|
||||||
|
.type = VSH_OT_BOOL,
|
||||||
|
.help = N_("show free pages for all NUMA cells")
|
||||||
|
},
|
||||||
|
{.name = NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cmdFreepages(vshControl *ctl, const vshCmd *cmd)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
unsigned int npages;
|
||||||
|
unsigned int *pagesize = NULL;
|
||||||
|
int cell;
|
||||||
|
unsigned long long *counts = NULL;
|
||||||
|
size_t i, j;
|
||||||
|
xmlNodePtr *nodes = NULL;
|
||||||
|
int nodes_cnt;
|
||||||
|
char *cap_xml = NULL;
|
||||||
|
xmlDocPtr doc = NULL;
|
||||||
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
|
bool all = vshCommandOptBool(cmd, "all");
|
||||||
|
bool cellno = vshCommandOptBool(cmd, "cellno");
|
||||||
|
|
||||||
|
VSH_EXCLUSIVE_OPTIONS_VAR(all, cellno);
|
||||||
|
|
||||||
|
if (all) {
|
||||||
|
if (!(cap_xml = virConnectGetCapabilities(ctl->conn))) {
|
||||||
|
vshError(ctl, "%s", _("unable to get node capabilities"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(doc = virXMLParseStringCtxt(cap_xml, _("capabilities"), &ctxt))) {
|
||||||
|
vshError(ctl, "%s", _("unable to parse node capabilities"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes_cnt = virXPathNodeSet("/capabilities/host/cpu/pages", ctxt, &nodes);
|
||||||
|
|
||||||
|
if (nodes_cnt <= 0) {
|
||||||
|
vshError(ctl, "%s", _("could not get information about "
|
||||||
|
"supported page sizes"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pagesize = vshMalloc(ctl, nodes_cnt * sizeof(*pagesize));
|
||||||
|
|
||||||
|
for (i = 0; i < nodes_cnt; i++) {
|
||||||
|
char *val = virXMLPropString(nodes[i], "size");
|
||||||
|
|
||||||
|
if (virStrToLong_ui(val, NULL, 10, &pagesize[i]) < 0) {
|
||||||
|
vshError(ctl, _("unable to parse page size: %s"), val);
|
||||||
|
VIR_FREE(val);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
npages = nodes_cnt;
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
|
counts = vshMalloc(ctl, npages * sizeof(*counts));
|
||||||
|
|
||||||
|
nodes_cnt = virXPathNodeSet("/capabilities/host/topology/cells/cell",
|
||||||
|
ctxt, &nodes);
|
||||||
|
for (i = 0; i < nodes_cnt; i++) {
|
||||||
|
char *val = virXMLPropString(nodes[i], "id");
|
||||||
|
|
||||||
|
if (virStrToLong_i(val, NULL, 10, &cell) < 0) {
|
||||||
|
vshError(ctl, _("unable to parse numa node id: %s"), val);
|
||||||
|
VIR_FREE(val);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
VIR_FREE(val);
|
||||||
|
|
||||||
|
if (virNodeGetFreePages(ctl->conn, npages, pagesize,
|
||||||
|
cell, 1, counts, 0) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
vshPrint(ctl, _("Node %d:\n"), cell);
|
||||||
|
for (j = 0; j < npages; j++) {
|
||||||
|
vshPrint(ctl, "%uKiB: %lld\n", pagesize[j], counts[j]);
|
||||||
|
}
|
||||||
|
vshPrint(ctl, "%c", '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!cellno) {
|
||||||
|
vshError(ctl, "%s", _("missing cellno argument"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vshCommandOptInt(cmd, "cellno", &cell) < 0) {
|
||||||
|
vshError(ctl, "%s", _("Invalid cellno argument"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell < -1) {
|
||||||
|
vshError(ctl, "%s", _("cell number must be non-negative integer or -1"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pagesize = vshMalloc(ctl, sizeof(*pagesize));
|
||||||
|
if (vshCommandOptScaledInt(cmd, "pagesize", (unsigned long long *) pagesize,
|
||||||
|
1, UINT_MAX) < 0) {
|
||||||
|
vshError(ctl, "%s", _("page size has to be a number"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* page size is expected in kibibytes */
|
||||||
|
pagesize[0] /= 1024;
|
||||||
|
|
||||||
|
if (!pagesize[0]) {
|
||||||
|
vshError(ctl, "%s", _("page size must be at least 1KiB"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
counts = vshMalloc(ctl, sizeof(*counts));
|
||||||
|
|
||||||
|
if (virNodeGetFreePages(ctl->conn, 1, pagesize, cell, 1, counts, 0) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
vshPrint(ctl, "%uKiB: %lld\n", *pagesize, counts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
cleanup:
|
||||||
|
xmlXPathFreeContext(ctxt);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
VIR_FREE(cap_xml);
|
||||||
|
VIR_FREE(nodes);
|
||||||
|
VIR_FREE(counts);
|
||||||
|
VIR_FREE(pagesize);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "maxvcpus" command
|
* "maxvcpus" command
|
||||||
*/
|
*/
|
||||||
@ -977,6 +1138,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
|
|||||||
.info = info_freecell,
|
.info = info_freecell,
|
||||||
.flags = 0
|
.flags = 0
|
||||||
},
|
},
|
||||||
|
{.name = "freepages",
|
||||||
|
.handler = cmdFreepages,
|
||||||
|
.opts = opts_freepages,
|
||||||
|
.info = info_freepages,
|
||||||
|
.flags = 0
|
||||||
|
},
|
||||||
{.name = "hostname",
|
{.name = "hostname",
|
||||||
.handler = cmdHostname,
|
.handler = cmdHostname,
|
||||||
.opts = NULL,
|
.opts = NULL,
|
||||||
|
@ -516,6 +516,14 @@ cell and the total free memory on the machine. Finally, with a
|
|||||||
numeric argument or with --cellno plus a cell number it will display
|
numeric argument or with --cellno plus a cell number it will display
|
||||||
the free memory for the specified cell only.
|
the free memory for the specified cell only.
|
||||||
|
|
||||||
|
=item B<freepages> [{ [I<--cellno>] I<cellno> [I<--pagesize>] I<pagesize> |
|
||||||
|
I<--all> }]
|
||||||
|
|
||||||
|
Prints the available amount of pages within a NUMA cell. I<cellno> refers
|
||||||
|
to the NUMA cell you're interested in. I<pagesize> is a scaled integer (see
|
||||||
|
B<NOTES> above). Alternatively, if I<--all> is used, info on each possible
|
||||||
|
combination of NUMA cell and page size is printed out.
|
||||||
|
|
||||||
=item B<cpu-baseline> I<FILE> [I<--features>]
|
=item B<cpu-baseline> I<FILE> [I<--features>]
|
||||||
|
|
||||||
Compute baseline CPU which will be supported by all host CPUs given in <file>.
|
Compute baseline CPU which will be supported by all host CPUs given in <file>.
|
||||||
|
Loading…
Reference in New Issue
Block a user