On Mon, 2014-11-03 at 14:18 +0100, Martin Kletzander wrote: > On Thu, Oct 30, 2014 at 01:44:18PM +0800, Chen Fan wrote: > >There was no check for 'nodeset' attribute in numatune-related > >elements. This patch adds validation that any nodeset specified does > >not exceed maximum host node. > > > >Signed-off-by: Chen Fan <chen.fan.fnst@xxxxxxxxxxxxxx> > >--- > > src/conf/numatune_conf.c | 28 ++++++++++++++++ > > src/conf/numatune_conf.h | 1 + > > src/libvirt_private.syms | 1 + > > src/qemu/qemu_command.c | 4 +++ > > src/util/virnuma.c | 38 ++++++++++++++++++++++ > > src/util/virnuma.h | 1 + > > ...rgv-numatune-static-nodeset-exceed-hostnode.xml | 36 ++++++++++++++++++++ > > tests/qemuxml2argvmock.c | 9 +++++ > > tests/qemuxml2argvtest.c | 1 + > > 9 files changed, 119 insertions(+) > > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml > > > >diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c > >index 21d9a64..6986739 100644 > >--- a/src/conf/numatune_conf.c > >+++ b/src/conf/numatune_conf.c > >@@ -612,3 +612,31 @@ virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune) > > > > return false; > > } > >+ > >+int > >+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune) > >+{ > >+ int ret = -1; > >+ virBitmapPtr nodemask = NULL; > >+ size_t i; > >+ int bit; > >+ > >+ if (!numatune) > >+ return ret; > >+ > >+ nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1); > >+ if (nodemask) > >+ ret = virBitmapLastSetBit(nodemask); > >+ > >+ for (i = 0; i < numatune->nmem_nodes; i++) { > >+ nodemask = numatune->mem_nodes[i].nodeset; > >+ if (!nodemask) > >+ continue; > >+ > >+ bit = virBitmapLastSetBit(nodemask); > >+ if (bit > ret) > >+ ret = bit; > >+ } > >+ > >+ return ret; > >+} > >diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h > >index 5254629..15dc0d6 100644 > >--- a/src/conf/numatune_conf.h > >+++ b/src/conf/numatune_conf.h > >@@ -102,4 +102,5 @@ bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune); > > > > bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune); > > > >+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune); > > #endif /* __NUMATUNE_CONF_H__ */ > >diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > >index 1e2bc0a..4a30ad7 100644 > >--- a/src/libvirt_private.syms > >+++ b/src/libvirt_private.syms > >@@ -1729,6 +1729,7 @@ virNumaGetPageInfo; > > virNumaGetPages; > > virNumaIsAvailable; > > virNumaNodeIsAvailable; > >+virNumaNodesetIsAvailable; > > virNumaSetPagePoolSize; > > virNumaSetupMemoryPolicy; > > > >diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > >index 2e5af4f..d2c5f0c 100644 > >--- a/src/qemu/qemu_command.c > >+++ b/src/qemu/qemu_command.c > >@@ -53,6 +53,7 @@ > > #include "virstoragefile.h" > > #include "virtpm.h" > > #include "virscsi.h" > >+#include "virnuma.h" > > #if defined(__linux__) > > # include <linux/capability.h> > > #endif > >@@ -6663,6 +6664,9 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, > > goto cleanup; > > } > > > >+ if (!virNumaNodesetIsAvailable(def->numatune)) > >+ goto cleanup; > >+ > > for (i = 0; i < def->mem.nhugepages; i++) { > > ssize_t next_bit, pos = 0; > > > >diff --git a/src/util/virnuma.c b/src/util/virnuma.c > >index 690615f..4188ef5 100644 > >--- a/src/util/virnuma.c > >+++ b/src/util/virnuma.c > >@@ -165,6 +165,33 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune, > > return ret; > > } > > > >+bool > >+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune) > >+{ > >+ int maxnode; > >+ int bit; > >+ > >+ if (!numatune) > >+ return true; > >+ > >+ bit = virDomainNumatuneSpecifiedMaxNode(numatune); > >+ if (bit == -1) > > (bit < 0) would go with the rest of the code, the functions can be > then modified to report various kinds of errors more easily. > > >+ return true; > >+ > >+ if ((maxnode = virNumaGetMaxNode()) < 0) > >+ return false; > >+ > >+ maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES; > >+ if (bit > maxnode) > >+ goto error; > >+ > >+ return true; > >+ > >+ error: > >+ virReportError(VIR_ERR_INTERNAL_ERROR, > >+ _("NUMA node %d is out of range"), bit); > >+ return false; > >+} > > > > bool > > virNumaIsAvailable(void) > >@@ -330,6 +357,17 @@ virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune, > > return 0; > > } > > > >+bool > >+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune) > >+{ > >+ if (virDomainNumatuneSpecifiedMaxNode(numatune) != -1) { > > similarly " >= 0" here. > > >+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > >+ _("libvirt is compiled without NUMA tuning support")); > >+ return false; > >+ } > >+ > >+ return true; > >+} > > > > bool > > virNumaIsAvailable(void) > >diff --git a/src/util/virnuma.h b/src/util/virnuma.h > >index 04b6b8c..5bb37b8 100644 > >--- a/src/util/virnuma.h > >+++ b/src/util/virnuma.h > >@@ -34,6 +34,7 @@ char *virNumaGetAutoPlacementAdvice(unsigned short vcups, > > int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune, > > virBitmapPtr nodemask); > > > >+bool virNumaNodesetIsAvailable(virDomainNumatunePtr numatune); > > bool virNumaIsAvailable(void); > > int virNumaGetMaxNode(void); > > bool virNumaNodeIsAvailable(int node); > >diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml b/tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml > >new file mode 100644 > >index 0000000..b7564fe > >--- /dev/null > >+++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-static-nodeset-exceed-hostnode.xml > >@@ -0,0 +1,36 @@ > >+<domain type='qemu'> > >+ <name>QEMUGuest1</name> > >+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> > >+ <memory unit='KiB'>1048576</memory> > >+ <currentMemory unit='KiB'>1048576</currentMemory> > >+ <vcpu placement='static'>4</vcpu> > >+ <numatune> > >+ <memnode cellid='0' mode='strict' nodeset='0-8'/> > >+ <memnode cellid='1' mode='strict' nodeset='0'/> > >+ </numatune> > >+ <os> > >+ <type arch='i686' machine='pc'>hvm</type> > >+ <boot dev='hd'/> > >+ </os> > >+ <cpu> > >+ <numa> > >+ <cell id='0' cpus='0-1' memory='524288'/> > >+ <cell id='1' cpus='2-3' memory='524288'/> > >+ </numa> > >+ </cpu> > >+ <clock offset='utc'/> > >+ <on_poweroff>destroy</on_poweroff> > >+ <on_reboot>restart</on_reboot> > >+ <on_crash>destroy</on_crash> > >+ <devices> > >+ <emulator>/usr/bin/qemu-system-x86_64</emulator> > >+ <disk type='block' device='disk'> > >+ <source dev='/dev/HostVG/QEMUGuest1'/> > >+ <target dev='hda' bus='ide'/> > >+ <address type='drive' controller='0' bus='0' target='0' unit='0'/> > >+ </disk> > >+ <controller type='ide' index='0'/> > >+ <memballoon model='virtio'/> > >+ </devices> > >+</domain> > >+ > > Empty line at EOF. "make syntax-check" would find that for you ;) > > >diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c > >index bff3b0f..7218747 100644 > >--- a/tests/qemuxml2argvmock.c > >+++ b/tests/qemuxml2argvmock.c > >@@ -21,6 +21,7 @@ > > #include <config.h> > > > > #include "internal.h" > >+#include "virnuma.h" > > #include <time.h> > > > > time_t time(time_t *t) > >@@ -30,3 +31,11 @@ time_t time(time_t *t) > > *t = ret; > > return ret; > > } > >+ > >+int > >+virNumaGetMaxNode(void) > >+{ > >+ const int maxnodesNum = 7; > >+ > >+ return maxnodesNum; > >+} > > Why not just "return 7;" ??? I just think magic number may be not proper. Thanks, Chen > > >diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > >index 0e9fab9..bab6d0d 100644 > >--- a/tests/qemuxml2argvtest.c > >+++ b/tests/qemuxml2argvtest.c > >@@ -1250,6 +1250,7 @@ mymain(void) > > DO_TEST_FAILURE("numatune-memnode-no-memory", NONE); > > > > DO_TEST("numatune-auto-nodeset-invalid", NONE); > >+ DO_TEST_FAILURE("numatune-static-nodeset-exceed-hostnode", QEMU_CAPS_OBJECT_MEMORY_RAM); > > Very long line. > > > DO_TEST_PARSE_ERROR("numatune-memnode-nocpu", NONE); > > DO_TEST_PARSE_ERROR("numatune-memnodes-problematic", NONE); > > DO_TEST("numad", NONE); > >-- > >1.9.3 > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list