Add NUMA topology support

libvirt has supported specification of a guest NUMA topology since
0.9.8. This functionality can be used for basic validation of some
NUMA-dependent features during development. Add basic configuration
support, by allowing the user to specify how many NUMA nodes the
instance may have.

The following options are added:

* numa_nodes - Defaults to none

For additional information on specifying NUMA nodes with Libvirt, see:

* https://libvirt.org/formatdomain.html#elementsCPU
This commit is contained in:
Stephen Finucane 2016-09-06 16:06:35 +01:00
parent 802e666b41
commit fec9fa4f6c
4 changed files with 36 additions and 0 deletions

View File

@ -237,6 +237,7 @@ end
* `cpu_fallback` - Whether to allow libvirt to fall back to a CPU model close
to the specified model if features in the guest CPU are not supported on the
host. Defaults to 'allow' if not set. Allowed values: `allow`, `forbid`.
* `numa_nodes` - Number of NUMA nodes on guest. Must be a factor of `cpu`.
* `loader` - Sets path to custom UEFI loader.
* `volume_cache` - Controls the cache mechanism. Possible values are "default",
"none", "writethrough", "writeback", "directsync" and "unsafe". [See

View File

@ -37,6 +37,7 @@ module VagrantPlugins
@cpu_mode = config.cpu_mode
@cpu_model = config.cpu_model
@cpu_fallback = config.cpu_fallback
@numa_nodes = config.numa_nodes
@loader = config.loader
@machine_type = config.machine_type
@machine_arch = config.machine_arch

View File

@ -62,6 +62,7 @@ module VagrantPlugins
attr_accessor :cpu_model
attr_accessor :cpu_fallback
attr_accessor :cpu_features
attr_accessor :numa_nodes
attr_accessor :loader
attr_accessor :boot_order
attr_accessor :machine_type
@ -143,6 +144,7 @@ module VagrantPlugins
@cpu_model = UNSET_VALUE
@cpu_fallback = UNSET_VALUE
@cpu_features = UNSET_VALUE
@numa_nodes = UNSET_VALUE
@loader = UNSET_VALUE
@machine_type = UNSET_VALUE
@machine_arch = UNSET_VALUE
@ -232,6 +234,29 @@ module VagrantPlugins
raise 'Only four cdroms may be attached at a time'
end
def _generate_numa
if @cpus % @numa_nodes != 0
raise 'NUMA nodes must be a factor of CPUs'
end
numa = []
(1..@numa_nodes).each do |node|
numa_cpu_start = (@cpus / @numa_nodes) * (node - 1)
numa_cpu_end = (@cpus / @numa_nodes) * node - 1
numa_cpu = Array(numa_cpu_start..numa_cpu_end).join(',')
numa_mem = @memory / @numa_nodes
numa.push({
id: node,
cpu: numa_cpu,
mem: numa_mem
})
end
@numa_nodes = numa
end
def cpu_feature(options={})
if options[:name].nil? || options[:policy].nil?
raise 'CPU Feature name AND policy must be specified'
@ -457,6 +482,7 @@ module VagrantPlugins
@cpu_model = 'qemu64' if @cpu_model == UNSET_VALUE
@cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE
@cpu_features = [] if @cpu_features == UNSET_VALUE
@numa_nodes = _generate_numa() if @numa_nodes != UNSET_VALUE
@loader = nil if @loader == UNSET_VALUE
@machine_type = nil if @machine_type == UNSET_VALUE
@machine_arch = nil if @machine_arch == UNSET_VALUE

View File

@ -15,6 +15,14 @@
<% @cpu_features.each do |cpu_feature| %>
<feature name='<%= cpu_feature[:name] %>' policy='<%= cpu_feature[:policy] %>'/>
<% end %>
<% else %>
<% if @numa_nodes %>
<numa>
<% @numa_nodes.each do |node| %>
<cell id='<%= node[:id] %>' cpus='<%= node[:cpu] %>' memory='<%= node[:mem] %>'/>
<% end %>
</numa>
<% end %>
<% end %>
</cpu>