From f69ece073e4511957580824cfe6366a04bac7366 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 2 Jul 2015 10:21:50 +0200 Subject: [PATCH] virsh: Teach cmdFreepages to work with lxc driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some drivers don't expose available huge page sizes in the capabilities XML. For instance, LXC driver is one of those. This has a downside that when virsh is trying to get aggregated info on free pages per all NUMA nodes, it fails. The problem is that the virNodeGetFreePages() API expects caller to pass an array of page sizes he is interested in. In virsh, this array is filled from the capabilities from '/capabilities/host/cpu/pages' XPath. As said, in LXC there's no such XPath and therefore virsh fails currently. But hey, we can fallback: the page sizes are exposed under '/capabilities/host/topology/cells/cell/pages'. The page size can be collected from there, and voilĂ  the command works again. But now we must make sure that there are no duplicates in the array passed to the public API. Otherwise we won't get as beautiful output as we are getting now. Signed-off-by: Michal Privoznik --- tools/virsh-host.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/tools/virsh-host.c b/tools/virsh-host.c index 66f7fd9e62..04ca1e5047 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -285,6 +285,15 @@ static const vshCmdOptDef opts_freepages[] = { {.name = NULL} }; +static int +vshPageSizeSorter(const void *a, const void *b) +{ + unsigned int pa = *(unsigned int *)a; + unsigned int pb = *(unsigned int *)b; + + return pa - pb; +} + static bool cmdFreepages(vshControl *ctl, const vshCmd *cmd) { @@ -326,9 +335,15 @@ cmdFreepages(vshControl *ctl, const vshCmd *cmd) 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; + /* Some drivers don't export page sizes under the + * XPath above. Do another trick to get them. */ + nodes_cnt = virXPathNodeSet("/capabilities/host/topology/cells/cell/pages", + ctxt, &nodes); + if (nodes_cnt <= 0) { + vshError(ctl, "%s", _("could not get information about " + "supported page sizes")); + goto cleanup; + } } pagesize = vshCalloc(ctl, nodes_cnt, sizeof(*pagesize)); @@ -345,6 +360,22 @@ cmdFreepages(vshControl *ctl, const vshCmd *cmd) VIR_FREE(val); } + /* Here, if we've done the trick few lines above, + * @pagesize array will contain duplicates. We should + * remove them otherwise not very nice output will be + * produced. */ + qsort(pagesize, nodes_cnt, sizeof(*pagesize), vshPageSizeSorter); + + for (i = 0; i < nodes_cnt - 1;) { + if (pagesize[i] == pagesize[i + 1]) { + memmove(pagesize + i, pagesize + i + 1, + (nodes_cnt - i + 1) * sizeof(*pagesize)); + nodes_cnt--; + } else { + i++; + } + } + npages = nodes_cnt; VIR_FREE(nodes); } else {