mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
virt: support cpu tunning and Iothread allocation
This commit is contained in:
parent
4fb4d12fdb
commit
50701b3573
4 changed files with 1262 additions and 15 deletions
|
@ -965,6 +965,7 @@ def _gen_xml(
|
|||
context["mem"] = nesthash(mem)
|
||||
|
||||
context["cpu"] = nesthash()
|
||||
context["cputune"] = nesthash()
|
||||
if isinstance(cpu, int):
|
||||
context["cpu"]["maximum"] = str(cpu)
|
||||
elif isinstance(cpu, dict):
|
||||
|
@ -1898,7 +1899,8 @@ def init(
|
|||
:param name: name of the virtual machine to create
|
||||
:param cpu:
|
||||
Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to configure
|
||||
cpu model and topology. The structure of the dictionary is documented in :ref:`init-cpu-def`.
|
||||
cpu model and topology, numa node tuning, cpu tuning and iothreads allocation. The structure of the dictionary is
|
||||
documented in :ref:`init-cpu-def`.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
@ -1939,7 +1941,7 @@ def init(
|
|||
memory: 1g
|
||||
discard: True
|
||||
distances:
|
||||
0: 10
|
||||
0: 10 # sibling id : value
|
||||
1: 21
|
||||
2: 31
|
||||
3: 41
|
||||
|
@ -1952,6 +1954,60 @@ def init(
|
|||
1: 10
|
||||
2: 21
|
||||
3: 31
|
||||
tuning:
|
||||
vcpupin:
|
||||
0: 1-4,^2 # vcpuid : cpuset
|
||||
1: 0,1
|
||||
2: 2,3
|
||||
3: 0,4
|
||||
emulatorpin: 1-3
|
||||
iothreadpin:
|
||||
1: 5,6 # iothread id: cpuset
|
||||
2: 7,8
|
||||
shares: 2048
|
||||
period: 1000000
|
||||
quota: -1
|
||||
global_period: 1000000
|
||||
global_quota: -1
|
||||
emulator_period: 1000000
|
||||
emulator_quota: -1
|
||||
iothread_period: 1000000
|
||||
iothread_quota: -1
|
||||
vcpusched:
|
||||
- scheduler: fifo
|
||||
priority: 1
|
||||
vcpus: 0,3-5
|
||||
- scheduler: rr
|
||||
priority: 3
|
||||
iothreadsched:
|
||||
- scheduler: idle
|
||||
- scheduler: batch
|
||||
iothreads: 2,3
|
||||
emulatorsched:
|
||||
- scheduler: batch
|
||||
cachetune:
|
||||
0-3: # vcpus set
|
||||
0: # cache id
|
||||
level: 3
|
||||
type: both
|
||||
size: 4
|
||||
1:
|
||||
level: 3
|
||||
type: both
|
||||
size: 6
|
||||
monitor:
|
||||
1: 3
|
||||
0-3: 3
|
||||
4-5:
|
||||
monitor:
|
||||
4: 3 # vcpus: level
|
||||
5: 3
|
||||
memorytune:
|
||||
0-3: # vcpus set
|
||||
0: 60 # node id: bandwidth
|
||||
4-5:
|
||||
0: 60
|
||||
iothreads: 4
|
||||
|
||||
.. versionadded:: Aluminium
|
||||
|
||||
|
@ -2147,6 +2203,76 @@ def init(
|
|||
element define the distance between NUMA cells and ``sibling`` sub-element is used to specify the distance value
|
||||
between sibling NUMA cells.
|
||||
|
||||
vcpupin
|
||||
The optional vcpupin element specifies which of host's physical CPUs the domain vCPU will be pinned to.
|
||||
|
||||
emulatorpin
|
||||
The optional emulatorpin element specifies which of host physical CPUs the "emulator", a subset of a domain not
|
||||
including vCPU or iothreads will be pinned to.
|
||||
|
||||
iothreadpin
|
||||
The optional iothreadpin element specifies which of host physical CPUs the IOThreads will be pinned to.
|
||||
|
||||
shares
|
||||
The optional shares element specifies the proportional weighted share for the domain.
|
||||
|
||||
period
|
||||
The optional period element specifies the enforcement interval (unit: microseconds).
|
||||
|
||||
quota
|
||||
The optional quota element specifies the maximum allowed bandwidth (unit: microseconds).
|
||||
|
||||
global_period
|
||||
The optional global_period element specifies the enforcement CFS scheduler interval (unit: microseconds) for the
|
||||
whole domain in contrast with period which enforces the interval per vCPU.
|
||||
|
||||
global_quota
|
||||
The optional global_quota element specifies the maximum allowed bandwidth (unit: microseconds) within a period
|
||||
for the whole domain.
|
||||
|
||||
emulator_period
|
||||
The optional emulator_period element specifies the enforcement interval (unit: microseconds).
|
||||
|
||||
emulator_quota
|
||||
The optional emulator_quota element specifies the maximum allowed bandwidth (unit: microseconds) for domain's
|
||||
emulator threads (those excluding vCPUs).
|
||||
|
||||
iothread_period
|
||||
The optional iothread_period element specifies the enforcement interval (unit: microseconds) for IOThreads.
|
||||
|
||||
iothread_quota
|
||||
The optional iothread_quota element specifies the maximum allowed bandwidth (unit: microseconds) for IOThreads.
|
||||
|
||||
vcpusched
|
||||
specify the scheduler type for vCPUs.
|
||||
The value is a list of dictionaries with the ``scheduler`` key (values ``batch``, ``idle``, ``fifo``, ``rr``)
|
||||
and the optional ``priority`` and ``vcpus`` keys. The ``priority`` value usually is a positive integer and the
|
||||
``vcpus`` value is a cpu set like ``1-4,^3,6`` or simply the vcpu id.
|
||||
|
||||
iothreadsched
|
||||
specify the scheduler type for IO threads.
|
||||
The value is a list of dictionaries with the ``scheduler`` key (values ``batch``, ``idle``, ``fifo``, ``rr``)
|
||||
and the optional ``priority`` and ``vcpus`` keys. The ``priority`` value usually is a positive integer and the
|
||||
``vcpus`` value is a cpu set like ``1-4,^3,6`` or simply the vcpu id.
|
||||
|
||||
emulatorsched
|
||||
specify the scheduler type (values batch, idle, fifo, rr) for particular the emulator.
|
||||
The value is a dictionary with the ``scheduler`` key (values ``batch``, ``idle``, ``fifo``, ``rr``)
|
||||
and the optional ``priority`` and ``vcpus`` keys. The ``priority`` value usually is a positive integer.
|
||||
|
||||
cachetune
|
||||
Optional cachetune element can control allocations for CPU caches using the resctrl on the host.
|
||||
|
||||
monitor
|
||||
The optional element monitor creates the cache monitor(s) for current cache allocation.
|
||||
|
||||
memorytune
|
||||
Optional memorytune element can control allocations for memory bandwidth using the resctrl on the host.
|
||||
|
||||
iothreads
|
||||
Number of threads for supported disk devices to perform I/O requests. iothread id will be numbered from 1 to
|
||||
the provided number (Default: None).
|
||||
|
||||
.. _init-boot-def:
|
||||
|
||||
.. rubric:: Boot parameters definition
|
||||
|
@ -2765,11 +2891,14 @@ def update(
|
|||
Update the definition of an existing domain.
|
||||
|
||||
:param name: Name of the domain to update
|
||||
:param cpu: Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to
|
||||
configure cpu model and topology. The structure of the dictionary is documented in :ref:`init-cpu-def`.
|
||||
To update any cpu/vcpu element specify the new values to the corresponding tag. To remove any element or
|
||||
attribute, specify ``None`` object. Please note that ``None`` object is mapped to ``null`` in yaml, use
|
||||
``null`` in sls file instead.
|
||||
:param cpu:
|
||||
Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to configure
|
||||
cpu model and topology, numa node tuning, cpu tuning and iothreads allocation. The structure of the dictionary is
|
||||
documented in :ref:`init-cpu-def`.
|
||||
|
||||
To update any cpu parameters specify the new values to the corresponding tag. To remove any element or attribute,
|
||||
specify ``None`` object. Please note that ``None`` object is mapped to ``null`` in yaml, use ``null`` in sls file
|
||||
instead.
|
||||
:param mem: Amount of memory to allocate to the virtual machine in MiB. Since 3002, a dictionary can be used to
|
||||
contain detailed configuration which support memory allocation or tuning. Supported parameters are ``boot``,
|
||||
``current``, ``max``, ``slots``, ``hard_limit``, ``soft_limit``, ``swap_hard_limit``, ``min_guarantee``,
|
||||
|
@ -3251,6 +3380,130 @@ def update(
|
|||
"set": lambda n, v: n.set("value", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("value", ["id"]),
|
||||
},
|
||||
{"path": "cpu:iothreads", "xpath": "iothreads"},
|
||||
{"path": "cpu:tuning:shares", "xpath": "cputune/shares"},
|
||||
{"path": "cpu:tuning:period", "xpath": "cputune/period"},
|
||||
{"path": "cpu:tuning:quota", "xpath": "cputune/quota"},
|
||||
{"path": "cpu:tuning:global_period", "xpath": "cputune/global_period"},
|
||||
{"path": "cpu:tuning:global_quota", "xpath": "cputune/global_quota"},
|
||||
{"path": "cpu:tuning:emulator_period", "xpath": "cputune/emulator_period"},
|
||||
{"path": "cpu:tuning:emulator_quota", "xpath": "cputune/emulator_quota"},
|
||||
{"path": "cpu:tuning:iothread_period", "xpath": "cputune/iothread_period"},
|
||||
{"path": "cpu:tuning:iothread_quota", "xpath": "cputune/iothread_quota"},
|
||||
{
|
||||
"path": "cpu:tuning:vcpupin:{id}",
|
||||
"xpath": "cputune/vcpupin[@vcpu='$id']",
|
||||
"get": lambda n: str(n.get("cpuset")) if n.get("cpuset") else None,
|
||||
"set": lambda n, v: n.set("cpuset", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("cpuset", ["vcpu"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:emulatorpin",
|
||||
"xpath": "cputune/emulatorpin",
|
||||
"get": lambda n: str(n.get("cpuset")) if n.get("cpuset") else None,
|
||||
"set": lambda n, v: n.set("cpuset", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("cpuset", []),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:iothreadpin:{id}",
|
||||
"xpath": "cputune/iothreadpin[@iothread='$id']",
|
||||
"get": lambda n: str(n.get("cpuset")) if n.get("cpuset") else None,
|
||||
"set": lambda n, v: n.set("cpuset", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("cpuset", ["iothread"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:vcpusched:{id}:scheduler",
|
||||
"xpath": "cputune/vcpusched[$id]",
|
||||
"get": lambda n: str(n.get("scheduler")),
|
||||
"set": lambda n, v: n.set("scheduler", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("scheduler", ["priority", "vcpus"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:vcpusched:{id}:priority",
|
||||
"xpath": "cputune/vcpusched[$id]",
|
||||
"get": lambda n: str(n.get("priority")) if n.get("priority") else None,
|
||||
"set": lambda n, v: n.set("priority", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("priority"),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:vcpusched:{id}:vcpus",
|
||||
"xpath": "cputune/vcpusched[$id]",
|
||||
"get": lambda n: str(n.get("vcpus")) if n.get("vcpus") else None,
|
||||
"set": lambda n, v: n.set("vcpus", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("vcpus"),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:iothreadsched:{id}:scheduler",
|
||||
"xpath": "cputune/iothreadsched[$id]",
|
||||
"get": lambda n: str(n.get("scheduler")),
|
||||
"set": lambda n, v: n.set("scheduler", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute(
|
||||
"scheduler", ["priority", "iothreads"]
|
||||
),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:iothreadsched:{id}:priority",
|
||||
"xpath": "cputune/iothreadsched[$id]",
|
||||
"get": lambda n: str(n.get("priority")) if n.get("priority") else None,
|
||||
"set": lambda n, v: n.set("priority", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("priority"),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:iothreadsched:{id}:iothreads",
|
||||
"xpath": "cputune/iothreadsched[$id]",
|
||||
"get": lambda n: str(n.get("iothreads")) if n.get("iothreads") else None,
|
||||
"set": lambda n, v: n.set("iothreads", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("iothreads"),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:emulatorsched:scheduler",
|
||||
"xpath": "cputune/emulatorsched",
|
||||
"get": lambda n: str(n.get("scheduler")),
|
||||
"set": lambda n, v: n.set("scheduler", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("scheduler", ["priority"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:emulatorsched:priority",
|
||||
"xpath": "cputune/emulatorsched",
|
||||
"get": lambda n: str(n.get("priority")) if n.get("priority") else None,
|
||||
"set": lambda n, v: n.set("priority", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("priority"),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:cachetune:{id}:{sid}:level",
|
||||
"xpath": "cputune/cachetune[@vcpus='$id']/cache[@id='$sid']",
|
||||
"get": lambda n: str(n.get("level")) if n.get("level") else None,
|
||||
"set": lambda n, v: n.set("level", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("level", ["id", "unit", "vcpus"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:cachetune:{id}:{sid}:type",
|
||||
"xpath": "cputune/cachetune[@vcpus='$id']/cache[@id='$sid']",
|
||||
"get": lambda n: str(n.get("type")) if n.get("type") else None,
|
||||
"set": lambda n, v: n.set("type", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("type", ["id", "unit", "vcpus"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:cachetune:{id}:{sid}:size",
|
||||
"xpath": "cputune/cachetune[@vcpus='$id']/cache[@id='$sid']",
|
||||
"get": lambda n: str(n.get("size")) if n.get("size") else None,
|
||||
"set": lambda n, v: n.set("size", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("size", ["id", "unit", "vcpus"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:cachetune:{id}:monitor:{sid}",
|
||||
"xpath": "cputune/cachetune[@vcpus='$id']/monitor[@vcpus='$sid']",
|
||||
"get": lambda n: str(n.get("level")) if n.get("level") else None,
|
||||
"set": lambda n, v: n.set("level", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("level", ["vcpus"]),
|
||||
},
|
||||
{
|
||||
"path": "cpu:tuning:memorytune:{id}:{sid}",
|
||||
"xpath": "cputune/memorytune[@vcpus='$id']/node[@id='$sid']",
|
||||
"get": lambda n: str(n.get("bandwidth")) if n.get("bandwidth") else None,
|
||||
"set": lambda n, v: n.set("bandwidth", str(v)),
|
||||
"del": salt.utils.xmlutil.del_attribute("bandwidth", ["id", "vcpus"]),
|
||||
},
|
||||
]
|
||||
|
||||
# update NUMA host policy
|
||||
|
|
|
@ -294,8 +294,122 @@ def defined(
|
|||
.. versionadded:: 3001
|
||||
|
||||
:param name: name of the virtual machine to run
|
||||
:param cpu: Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to configure
|
||||
cpu model and topology. The structure of the dictionary is documented in :ref:`init-cpu-def`.
|
||||
:param cpu:
|
||||
Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to configure
|
||||
cpu model and topology, numa node tuning, cpu tuning and iothreads allocation. The structure of the dictionary is
|
||||
documented in :ref:`init-cpu-def`.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
cpu:
|
||||
placement: static
|
||||
cpuset: 0-11
|
||||
current: 5
|
||||
maximum: 12
|
||||
vcpus:
|
||||
0:
|
||||
enabled: 'yes'
|
||||
hotpluggable: 'no'
|
||||
order: 1
|
||||
1:
|
||||
enabled: 'no'
|
||||
hotpluggable: 'yes'
|
||||
match: minimum
|
||||
mode: custom
|
||||
check: full
|
||||
vendor: Intel
|
||||
model:
|
||||
name: core2duo
|
||||
fallback: allow
|
||||
vendor_id: GenuineIntel
|
||||
topology:
|
||||
sockets: 1
|
||||
cores: 12
|
||||
threads: 1
|
||||
cache:
|
||||
level: 3
|
||||
mode: emulate
|
||||
feature:
|
||||
policy: optional
|
||||
name: lahf_lm
|
||||
numa:
|
||||
0:
|
||||
cpus: 0-3
|
||||
memory: 1g
|
||||
discard: 'yes'
|
||||
distances:
|
||||
0: 10 # sibling id : value
|
||||
1: 21
|
||||
2: 31
|
||||
3: 41
|
||||
1:
|
||||
cpus: 4-6
|
||||
memory: 1g
|
||||
memAccess: shared
|
||||
distances:
|
||||
0: 21
|
||||
1: 10
|
||||
2: 21
|
||||
3: 31
|
||||
tuning:
|
||||
vcpupin:
|
||||
0: 1-4,^2 # vcpuid : cpuset
|
||||
1: 0,1
|
||||
2: 2,3
|
||||
3: 0,4
|
||||
emulatorpin: 1-3
|
||||
iothreadpin:
|
||||
1: 5,6 # iothread id: cpuset
|
||||
2: 7,8
|
||||
shares: 2048
|
||||
period: 1000000
|
||||
quota: -1
|
||||
global_period: 1000000
|
||||
global_quota: -1
|
||||
emulator_period: 1000000
|
||||
emulator_quota: -1
|
||||
iothread_period: 1000000
|
||||
iothread_quota: -1
|
||||
vcpusched:
|
||||
- scheduler: fifo
|
||||
priority: 1
|
||||
- scheduler: fifo
|
||||
priority: 2
|
||||
vcpus: 1-3
|
||||
- scheduler: rr
|
||||
priority: 3
|
||||
vcpus: 4
|
||||
iothreadsched:
|
||||
- scheduler: batch
|
||||
iothreads: 2
|
||||
emulatorsched:
|
||||
scheduler: idle
|
||||
cachetune:
|
||||
0-3: # vcpus set
|
||||
0: # cache id
|
||||
level: 3
|
||||
type: both
|
||||
size: 4
|
||||
1:
|
||||
level: 3
|
||||
type: both
|
||||
size: 6
|
||||
monitor:
|
||||
1: 3
|
||||
0-3: 3
|
||||
4-5:
|
||||
monitor:
|
||||
4: 3 # vcpus: level
|
||||
5: 3
|
||||
memorytune:
|
||||
0-3: # vcpus set
|
||||
0: 60 # node id: bandwidth
|
||||
4-5:
|
||||
0: 60
|
||||
iothreads: 4
|
||||
|
||||
.. versionadded:: Aluminium
|
||||
|
||||
:param mem: Amount of memory to allocate to the virtual machine in MiB. Since 3002, a dictionary can be used to
|
||||
contain detailed configuration which support memory allocation or tuning. Supported parameters are ``boot``,
|
||||
``current``, ``max``, ``slots``, ``hard_limit``, ``soft_limit``, ``swap_hard_limit``, ``min_guarantee``,
|
||||
|
@ -544,12 +658,14 @@ def running(
|
|||
.. versionadded:: 2016.3.0
|
||||
|
||||
:param name: name of the virtual machine to run
|
||||
:param cpu: Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to
|
||||
configure cpu model and topology. The structure of the dictionary is documented in :ref:`init-cpu-def`.
|
||||
:param cpu:
|
||||
Number of virtual CPUs to assign to the virtual machine or a dictionary with detailed information to configure
|
||||
cpu model and topology, numa node tuning, cpu tuning and iothreads allocation. The structure of the dictionary is
|
||||
documented in :ref:`init-cpu-def`.
|
||||
|
||||
To update any cpu/vcpu element specify the new values to the corresponding tag. To remove any element or
|
||||
attribute,specify ``None`` object. Please note that ``None`` object is mapped to ``null`` in yaml, use ``null``
|
||||
in sls file instead.
|
||||
To update any cpu parameters specify the new values to the corresponding tag. To remove any element or attribute,
|
||||
specify ``None`` object. Please note that ``None`` object is mapped to ``null`` in yaml, use ``null`` in sls file
|
||||
instead.
|
||||
:param mem: Amount of memory to allocate to the virtual machine in MiB. Since 3002, a dictionary can be used to
|
||||
contain detailed configuration which support memory allocation or tuning. Supported parameters are ``boot``,
|
||||
``current``, ``max``, ``slots``, ``hard_limit``, ``soft_limit``, ``swap_hard_limit``, ``min_guarantee``,
|
||||
|
@ -672,6 +788,18 @@ def running(
|
|||
|
||||
.. versionadded:: Aluminium
|
||||
|
||||
:param numatune:
|
||||
The optional numatune element provides details of how to tune the performance of a NUMA host via controlling NUMA
|
||||
policy for domain process. The optional ``memory`` element specifies how to allocate memory for the domain process
|
||||
on a NUMA host. ``memnode`` elements can specify memory allocation policies per each guest NUMA node. The definition
|
||||
used in the dictionary can be found at :ref:`init-cpu-def`.
|
||||
|
||||
To update any numatune parameters, specify the new value. To remove any ``numatune`` parameters, pass a None object,
|
||||
for instance: 'numatune': ``None``. Please note that ``None`` is mapped to ``null`` in sls file, pass ``null`` in
|
||||
sls file instead.
|
||||
|
||||
.. versionadded:: Aluminium
|
||||
|
||||
.. rubric:: Example States
|
||||
|
||||
Make sure an already-defined virtual machine called ``domain_name`` is running:
|
||||
|
|
|
@ -51,6 +51,98 @@
|
|||
</numa>
|
||||
{%- endif %}
|
||||
</cpu>
|
||||
{%- if cpu.iothreads %}
|
||||
<iothreads>{{ cpu.iothreads }}</iothreads>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning %}
|
||||
<cputune>
|
||||
{%- if cpu.tuning.vcpupin %}
|
||||
{%- for vcpu_id, cpuset in cpu.tuning.vcpupin.items() %}
|
||||
<vcpupin vcpu='{{ vcpu_id }}' cpuset='{{ cpuset }}'/>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.emulatorpin %}
|
||||
<emulatorpin cpuset="{{ cpu.tuning.emulatorpin }}"/>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.iothreadpin %}
|
||||
{%- for thread_id, cpuset in cpu.tuning.iothreadpin.items() %}
|
||||
<iothreadpin iothread='{{ thread_id }}' cpuset='{{ cpuset }}'/>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.shares %}
|
||||
<shares>{{ cpu.tuning.shares }}</shares>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.period %}
|
||||
<period>{{ cpu.tuning.period }}</period>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.quota %}
|
||||
<quota>{{ cpu.tuning.quota }}</quota>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.global_period %}
|
||||
<global_period>{{ cpu.tuning.global_period }}</global_period>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.global_quota %}
|
||||
<global_quota>{{ cpu.tuning.global_quota }}</global_quota>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.emulator_period %}
|
||||
<emulator_period>{{ cpu.tuning.emulator_period }}</emulator_period>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.emulator_quota %}
|
||||
<emulator_quota>{{ cpu.tuning.emulator_quota }}</emulator_quota>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.iothread_period %}
|
||||
<iothread_period>{{ cpu.tuning.iothread_period }}</iothread_period>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.iothread_quota %}
|
||||
<iothread_quota>{{ cpu.tuning.iothread_quota }}</iothread_quota>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.vcpusched %}
|
||||
{%- for sched in cpu.tuning.vcpusched %}
|
||||
<vcpusched scheduler='{{ sched.scheduler }}'
|
||||
{%- if sched.get("vcpus") %} vcpus='{{ sched.get("vcpus") }}'{% endif -%}
|
||||
{%- if sched.get("priority") is not none %} priority='{{ sched.get("priority") }}'{% endif -%}
|
||||
/>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.iothreadsched %}
|
||||
{%- for sched in cpu.tuning.iothreadsched %}
|
||||
<iothreadsched scheduler='{{ sched.scheduler }}'
|
||||
{%- if sched.get("iothreads") %} iothreads='{{ sched.get("iothreads") }}'{% endif -%}
|
||||
{%- if sched.get("priority") is not none %} priority='{{ sched.get("priority") }}'{% endif -%}
|
||||
/>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.emulatorsched %}
|
||||
<emulatorsched scheduler='{{ cpu.tuning.emulatorsched.scheduler }}'
|
||||
{%- if cpu.tuning.emulatorsched.get("priority") is not none %} priority='{{ cpu.tuning.emulatorsched.get("priority") }}'{% endif -%}
|
||||
/>
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.cachetune %}
|
||||
{%- for k, v in cpu.tuning.cachetune.items() %}
|
||||
<cachetune vcpus='{{ k }}'>
|
||||
{%- for e, atrs in v.items() %}
|
||||
{%- if e is number and atrs %}
|
||||
<cache id='{{ e }}' {%- for atr, val in atrs.items() %} {{ atr }}='{{ val }}' {%- endfor %} />
|
||||
{%- elif e is not number %}
|
||||
{%- for atr, val in atrs.items() %}
|
||||
<monitor level='{{ val }}' vcpus='{{ atr }}'/>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</cachetune>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if cpu.tuning.memorytune %}
|
||||
{%- for vcpus, nodes in cpu.tuning.memorytune.items() %}
|
||||
<memorytune vcpus='{{ vcpus}}'>
|
||||
{%- for id, bandwidth in nodes.items() %}
|
||||
<node id='{{ id }}' bandwidth='{{ bandwidth }}'/>
|
||||
{%- endfor %}
|
||||
</memorytune>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
</cputune>
|
||||
{%- endif %}
|
||||
{%- if mem.max %}
|
||||
<maxMemory {{ opt_attribute(mem, 'slots') }} unit='KiB'>{{ to_kib(mem.max) }}</maxMemory>
|
||||
|
@ -81,7 +173,7 @@
|
|||
<numatune>
|
||||
{%- if 'memory' in numatune and numatune.memory %}
|
||||
<memory mode='{{ numatune.memory.mode }}'
|
||||
{%- if numatune.memory.nodeset %}nodeset='{{ numatune.memory.nodeset }}'{%- endif %}
|
||||
{%- if numatune.memory.nodeset %} nodeset='{{ numatune.memory.nodeset }}'{%- endif %}
|
||||
/>
|
||||
{%- endif %}
|
||||
{%- if 'memnodes' in numatune and numatune.memnodes %}
|
||||
|
|
|
@ -666,6 +666,187 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
|
|||
{"0": "20", "1": "10"},
|
||||
)
|
||||
|
||||
def test_gen_xml_cputune(self):
|
||||
"""
|
||||
Test virt._gen_xml() with CPU tuning
|
||||
"""
|
||||
diskp = virt._disk_profile(self.mock_conn, "default", "kvm", [], "hello")
|
||||
nicp = virt._nic_profile("default", "kvm")
|
||||
cputune = {
|
||||
"shares": 2048,
|
||||
"period": 122000,
|
||||
"quota": -1,
|
||||
"global_period": 1000000,
|
||||
"global_quota": -3,
|
||||
"emulator_period": 1200000,
|
||||
"emulator_quota": -10,
|
||||
"iothread_period": 133000,
|
||||
"iothread_quota": -1,
|
||||
"vcpupin": {0: "1-4,^2", 1: "0,1", 2: "2,3", 3: "0,4"},
|
||||
"emulatorpin": "1-3",
|
||||
"iothreadpin": {1: "5-6", 2: "7-8"},
|
||||
"vcpusched": [
|
||||
{"scheduler": "fifo", "priority": 1, "vcpus": "0"},
|
||||
{"scheduler": "fifo", "priority": 2, "vcpus": "1"},
|
||||
{"scheduler": "idle", "priority": 3, "vcpus": "2"},
|
||||
],
|
||||
"iothreadsched": [
|
||||
{"scheduler": "idle"},
|
||||
{"scheduler": "batch", "iothreads": "5-7", "priority": 1},
|
||||
],
|
||||
"emulatorsched": {"scheduler": "rr", "priority": 2},
|
||||
"cachetune": {
|
||||
"0-3": {
|
||||
0: {"level": 3, "type": "both", "size": 3},
|
||||
1: {"level": 3, "type": "both", "size": 3},
|
||||
"monitor": {1: 3, "0-3": 3},
|
||||
},
|
||||
"4-5": {"monitor": {4: 3, 5: 2}},
|
||||
},
|
||||
"memorytune": {"0-2": {0: 60}, "3-4": {0: 50, 1: 70}},
|
||||
}
|
||||
xml_data = virt._gen_xml(
|
||||
self.mock_conn,
|
||||
"hello",
|
||||
{"maximum": 1, "tuning": cputune, "iothreads": 2},
|
||||
512,
|
||||
diskp,
|
||||
nicp,
|
||||
"kvm",
|
||||
"hvm",
|
||||
"x86_64",
|
||||
)
|
||||
root = ET.fromstring(xml_data)
|
||||
self.assertEqual(root.find("cputune").find("shares").text, "2048")
|
||||
self.assertEqual(root.find("cputune").find("period").text, "122000")
|
||||
self.assertEqual(root.find("cputune").find("quota").text, "-1")
|
||||
self.assertEqual(root.find("cputune").find("global_period").text, "1000000")
|
||||
self.assertEqual(root.find("cputune").find("global_quota").text, "-3")
|
||||
self.assertEqual(root.find("cputune").find("emulator_period").text, "1200000")
|
||||
self.assertEqual(root.find("cputune").find("emulator_quota").text, "-10")
|
||||
self.assertEqual(root.find("cputune").find("iothread_period").text, "133000")
|
||||
self.assertEqual(root.find("cputune").find("iothread_quota").text, "-1")
|
||||
self.assertEqual(
|
||||
root.find("cputune").find("vcpupin[@vcpu='0']").attrib.get("cpuset"),
|
||||
"1-4,^2",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune").find("vcpupin[@vcpu='1']").attrib.get("cpuset"), "0,1",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune").find("vcpupin[@vcpu='2']").attrib.get("cpuset"), "2,3",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune").find("vcpupin[@vcpu='3']").attrib.get("cpuset"), "0,4",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune").find("emulatorpin").attrib.get("cpuset"), "1-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune")
|
||||
.find("iothreadpin[@iothread='1']")
|
||||
.attrib.get("cpuset"),
|
||||
"5-6",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("cputune")
|
||||
.find("iothreadpin[@iothread='2']")
|
||||
.attrib.get("cpuset"),
|
||||
"7-8",
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
s.get("vcpus"): {
|
||||
"scheduler": s.get("scheduler"),
|
||||
"priority": s.get("priority"),
|
||||
}
|
||||
for s in root.findall("cputune/vcpusched")
|
||||
},
|
||||
{
|
||||
"0": {"scheduler": "fifo", "priority": "1"},
|
||||
"1": {"scheduler": "fifo", "priority": "2"},
|
||||
"2": {"scheduler": "idle", "priority": "3"},
|
||||
},
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
s.get("iothreads"): {
|
||||
"scheduler": s.get("scheduler"),
|
||||
"priority": s.get("priority"),
|
||||
}
|
||||
for s in root.findall("cputune/iothreadsched")
|
||||
},
|
||||
{
|
||||
None: {"scheduler": "idle", "priority": None},
|
||||
"5-7": {"scheduler": "batch", "priority": "1"},
|
||||
},
|
||||
)
|
||||
self.assertEqual(root.find("cputune/emulatorsched").get("scheduler"), "rr")
|
||||
self.assertEqual(root.find("cputune/emulatorsched").get("priority"), "2")
|
||||
self.assertEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='0-3']").attrib.get("vcpus"), "0-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"level"
|
||||
),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"type"
|
||||
),
|
||||
"both",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find(
|
||||
"./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertNotEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"), None
|
||||
)
|
||||
self.assertNotEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='4-5']").attrib.get("vcpus"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/cachetune[@vcpus='4-5']/cache[@id='0']"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='4']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='5']"
|
||||
).attrib.get("level"),
|
||||
"2",
|
||||
)
|
||||
self.assertNotEqual(root.find("./cputune/memorytune[@vcpus='0-2']"), None)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/memorytune[@vcpus='0-2']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"60",
|
||||
)
|
||||
self.assertNotEqual(root.find("./cputune/memorytune[@vcpus='3-4']"), None)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/memorytune[@vcpus='3-4']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"50",
|
||||
)
|
||||
self.assertEqual(
|
||||
root.find("./cputune/memorytune[@vcpus='3-4']/node[@id='1']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"70",
|
||||
)
|
||||
self.assertEqual(root.find("iothreads").text, "2")
|
||||
|
||||
def test_default_disk_profile_hypervisor_esxi(self):
|
||||
"""
|
||||
Test virt._disk_profile() default ESXi profile
|
||||
|
@ -2665,6 +2846,179 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
|
|||
self.assertEqual(setxml.find("./memoryBacking/access").attrib["mode"], "shared")
|
||||
self.assertNotEqual(setxml.find("./memoryBacking/discard"), None)
|
||||
|
||||
# test adding iothreads
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": True,
|
||||
},
|
||||
virt.update("my_vm", cpu={"iothreads": 5}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("iothreads").text, "5")
|
||||
|
||||
# test adding cpu tune parameters
|
||||
cputune = {
|
||||
"shares": 2048,
|
||||
"period": 122000,
|
||||
"quota": -1,
|
||||
"global_period": 1000000,
|
||||
"global_quota": -3,
|
||||
"emulator_period": 1200000,
|
||||
"emulator_quota": -10,
|
||||
"iothread_period": 133000,
|
||||
"iothread_quota": -1,
|
||||
"vcpupin": {0: "1-4,^2", 1: "0,1", 2: "2,3", 3: "0,4"},
|
||||
"emulatorpin": "1-3",
|
||||
"iothreadpin": {1: "5-6", 2: "7-8"},
|
||||
"vcpusched": [
|
||||
{"scheduler": "fifo", "priority": 1, "vcpus": "0"},
|
||||
{"scheduler": "fifo", "priotity": 2, "vcpus": "1"},
|
||||
{"scheduler": "idle", "priotity": 3, "vcpus": "2"},
|
||||
],
|
||||
"iothreadsched": [{"scheduler": "batch", "iothreads": "7"}],
|
||||
"cachetune": {
|
||||
"0-3": {
|
||||
0: {"level": 3, "type": "both", "size": 3},
|
||||
1: {"level": 3, "type": "both", "size": 3},
|
||||
"monitor": {1: 3, "0-3": 3},
|
||||
},
|
||||
"4-5": {"monitor": {4: 3, 5: 2}},
|
||||
},
|
||||
"memorytune": {"0-2": {0: 60}, "3-4": {0: 50, 1: 70}},
|
||||
}
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": True,
|
||||
},
|
||||
virt.update("my_vm", cpu={"tuning": cputune}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("cputune").find("shares").text, "2048")
|
||||
self.assertEqual(setxml.find("cputune").find("period").text, "122000")
|
||||
self.assertEqual(setxml.find("cputune").find("quota").text, "-1")
|
||||
self.assertEqual(setxml.find("cputune").find("global_period").text, "1000000")
|
||||
self.assertEqual(setxml.find("cputune").find("global_quota").text, "-3")
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_period").text, "1200000")
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_quota").text, "-10")
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_period").text, "133000")
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_quota").text, "-1")
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='0']").attrib.get("cpuset"),
|
||||
"1-4,^2",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='1']").attrib.get("cpuset"),
|
||||
"0,1",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='2']").attrib.get("cpuset"),
|
||||
"2,3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='3']").attrib.get("cpuset"),
|
||||
"0,4",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("emulatorpin").attrib.get("cpuset"), "1-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("iothreadpin[@iothread='1']")
|
||||
.attrib.get("cpuset"),
|
||||
"5-6",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("iothreadpin[@iothread='2']")
|
||||
.attrib.get("cpuset"),
|
||||
"7-8",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpusched[@vcpus='0']").attrib.get("priority"),
|
||||
"1",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("vcpusched[@vcpus='0']")
|
||||
.attrib.get("scheduler"),
|
||||
"fifo",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("iothreadsched").attrib.get("iothreads"), "7"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("iothreadsched").attrib.get("scheduler"),
|
||||
"batch",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']").attrib.get("vcpus"), "0-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"level"
|
||||
),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"type"
|
||||
),
|
||||
"both",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertNotEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"), None
|
||||
)
|
||||
self.assertNotEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='4-5']").attrib.get("vcpus"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='4-5']/cache[@id='0']"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='4']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='5']"
|
||||
).attrib.get("level"),
|
||||
"2",
|
||||
)
|
||||
self.assertNotEqual(setxml.find("./cputune/memorytune[@vcpus='0-2']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='0-2']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"60",
|
||||
)
|
||||
self.assertNotEqual(setxml.find("./cputune/memorytune[@vcpus='3-4']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"50",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='1']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"70",
|
||||
)
|
||||
|
||||
# Update disks case
|
||||
devattach_mock = MagicMock(return_value=0)
|
||||
devdetach_mock = MagicMock(return_value=0)
|
||||
|
@ -4454,6 +4808,426 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
|
|||
virt.update("vm_with_memback_param", mem=unchanged_page),
|
||||
)
|
||||
|
||||
def test_update_iothreads_params(self):
|
||||
"""
|
||||
Test virt.update() with iothreads parameters.
|
||||
"""
|
||||
xml_with_iothreads_params = """
|
||||
<domain type='kvm' id='8'>
|
||||
<name>xml_with_iothreads_params</name>
|
||||
<memory unit='KiB'>1048576</memory>
|
||||
<currentMemory unit='KiB'>1048576</currentMemory>
|
||||
<maxMemory slots="12" unit="KiB">1048576</maxMemory>
|
||||
<vcpu placement='auto'>1</vcpu>
|
||||
<iothreads>6</iothreads>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-i440fx-2.6'>hvm</type>
|
||||
</os>
|
||||
</domain>
|
||||
"""
|
||||
domain_mock = self.set_mock_vm(
|
||||
"xml_with_iothreads_params", xml_with_iothreads_params
|
||||
)
|
||||
domain_mock.OSType = MagicMock(return_value="hvm")
|
||||
define_mock = MagicMock(return_value=True)
|
||||
self.mock_conn.defineXML = define_mock
|
||||
|
||||
# test updating existing iothreads
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": False,
|
||||
},
|
||||
virt.update("xml_with_iothreads_params", cpu={"iothreads": 7}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("iothreads").text, "7")
|
||||
|
||||
def test_update_cputune_paramters(self):
|
||||
"""
|
||||
Test virt.update() with cputune parameters.
|
||||
"""
|
||||
xml_with_cputune_params = """
|
||||
<domain type='kvm' id='8'>
|
||||
<name>xml_with_cputune_params</name>
|
||||
<memory unit='KiB'>1048576</memory>
|
||||
<currentMemory unit='KiB'>1048576</currentMemory>
|
||||
<maxMemory slots="12" unit="KiB">1048576</maxMemory>
|
||||
<vcpu placement='auto'>1</vcpu>
|
||||
<iothreads>4</iothreads>
|
||||
<cputune>
|
||||
<shares>2048</shares>
|
||||
<period>1000000</period>
|
||||
<quota>-1</quota>
|
||||
<global_period>1000000</global_period>
|
||||
<global_quota>-1</global_quota>
|
||||
<emulator_period>1000000</emulator_period>
|
||||
<emulator_quota>-1</emulator_quota>
|
||||
<iothread_period>1000000</iothread_period>
|
||||
<iothread_quota>-1</iothread_quota>
|
||||
<vcpupin vcpu="0" cpuset="0-2"/>
|
||||
<vcpupin vcpu="1" cpuset="3"/>
|
||||
<vcpupin vcpu="2" cpuset="4"/>
|
||||
<vcpupin vcpu="3" cpuset="5-7"/>
|
||||
<emulatorpin cpuset="1-2"/>
|
||||
<iothreadpin iothread="1" cpuset="1-5"/>
|
||||
<iothreadpin iothread="2" cpuset="6-7"/>
|
||||
<vcpusched vcpus="0" scheduler="idle" priority="3"/>
|
||||
<vcpusched vcpus="1" scheduler="rr" priority="1"/>
|
||||
<vcpusched vcpus="2" scheduler="fifo" priority="2"/>
|
||||
<iothreadsched iothreads="4" scheduler="fifo"/>
|
||||
<emulatorsched scheduler="idle"/>
|
||||
<cachetune vcpus="0-4">
|
||||
<cache id="0" level="2" type="both" size="4" unit="KiB"/>
|
||||
<cache id="1" level="2" type="both" size="4" unit="KiB"/>
|
||||
<monitor level="5" vcpus="0-2"/>
|
||||
<monitor level="6" vcpus="1-3"/>
|
||||
</cachetune>
|
||||
<cachetune vcpus="5-8">
|
||||
<monitor level="5" vcpus="5-6"/>
|
||||
<monitor level="3" vcpus="7-8"/>
|
||||
</cachetune>
|
||||
<memorytune vcpus="0-6">
|
||||
<node id="0" bandwidth="45"/>
|
||||
</memorytune>
|
||||
<memorytune vcpus="7-8">
|
||||
<node id="0" bandwidth="120"/>
|
||||
</memorytune>
|
||||
</cputune>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-i440fx-2.6'>hvm</type>
|
||||
</os>
|
||||
</domain>
|
||||
"""
|
||||
domain_mock = self.set_mock_vm(
|
||||
"xml_with_cputune_params", xml_with_cputune_params
|
||||
)
|
||||
domain_mock.OSType = MagicMock(return_value="hvm")
|
||||
define_mock = MagicMock(return_value=True)
|
||||
self.mock_conn.defineXML = define_mock
|
||||
|
||||
# test updating existing cputune parameters
|
||||
cputune = {
|
||||
"shares": 1024,
|
||||
"period": 5000,
|
||||
"quota": -20,
|
||||
"global_period": 4000,
|
||||
"global_quota": -30,
|
||||
"emulator_period": 3000,
|
||||
"emulator_quota": -4,
|
||||
"iothread_period": 7000,
|
||||
"iothread_quota": -5,
|
||||
"vcpupin": {0: "1-4,^2", 1: "0,1", 2: "2,3", 3: "0,4"},
|
||||
"emulatorpin": "1-3",
|
||||
"iothreadpin": {1: "5-6", 2: "7-8"},
|
||||
"vcpusched": [
|
||||
{"scheduler": "fifo", "priority": 1, "vcpus": "0"},
|
||||
{"scheduler": "fifo", "priority": 2, "vcpus": "1"},
|
||||
{"scheduler": "idle", "priority": 3, "vcpus": "2"},
|
||||
],
|
||||
"iothreadsched": [
|
||||
{"scheduler": "batch", "iothreads": "5-7", "priority": 1}
|
||||
],
|
||||
"emulatorsched": {"scheduler": "rr", "priority": 2},
|
||||
"cachetune": {
|
||||
"0-3": {
|
||||
0: {"level": 3, "type": "both", "size": 3},
|
||||
1: {"level": 3, "type": "both", "size": 3},
|
||||
"monitor": {1: 3, "0-3": 3},
|
||||
},
|
||||
"4-5": {"monitor": {4: 3, 5: 2}},
|
||||
},
|
||||
"memorytune": {"0-2": {0: 60}, "3-4": {0: 50, 1: 70}},
|
||||
}
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": False,
|
||||
},
|
||||
virt.update("xml_with_cputune_params", cpu={"tuning": cputune}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("cputune").find("shares").text, "1024")
|
||||
self.assertEqual(setxml.find("cputune").find("period").text, "5000")
|
||||
self.assertEqual(setxml.find("cputune").find("quota").text, "-20")
|
||||
self.assertEqual(setxml.find("cputune").find("global_period").text, "4000")
|
||||
self.assertEqual(setxml.find("cputune").find("global_quota").text, "-30")
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_period").text, "3000")
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_quota").text, "-4")
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_period").text, "7000")
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_quota").text, "-5")
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='0']").attrib.get("cpuset"),
|
||||
"1-4,^2",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='1']").attrib.get("cpuset"),
|
||||
"0,1",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='2']").attrib.get("cpuset"),
|
||||
"2,3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='3']").attrib.get("cpuset"),
|
||||
"0,4",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("emulatorpin").attrib.get("cpuset"), "1-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("iothreadpin[@iothread='1']")
|
||||
.attrib.get("cpuset"),
|
||||
"5-6",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("iothreadpin[@iothread='2']")
|
||||
.attrib.get("cpuset"),
|
||||
"7-8",
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
s.get("vcpus"): {
|
||||
"scheduler": s.get("scheduler"),
|
||||
"priority": s.get("priority"),
|
||||
}
|
||||
for s in setxml.findall("cputune/vcpusched")
|
||||
},
|
||||
{
|
||||
"0": {"scheduler": "fifo", "priority": "1"},
|
||||
"1": {"scheduler": "fifo", "priority": "2"},
|
||||
"2": {"scheduler": "idle", "priority": "3"},
|
||||
},
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
s.get("iothreads"): {
|
||||
"scheduler": s.get("scheduler"),
|
||||
"priority": s.get("priority"),
|
||||
}
|
||||
for s in setxml.findall("cputune/iothreadsched")
|
||||
},
|
||||
{"5-7": {"scheduler": "batch", "priority": "1"}},
|
||||
)
|
||||
self.assertEqual(setxml.find("cputune/emulatorsched").get("scheduler"), "rr")
|
||||
self.assertEqual(setxml.find("cputune/emulatorsched").get("priority"), "2")
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']").attrib.get("vcpus"), "0-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"level"
|
||||
),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"type"
|
||||
),
|
||||
"both",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertNotEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1']"), None
|
||||
)
|
||||
self.assertNotEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='4-5']").attrib.get("vcpus"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='4-5']/cache[@id='0']"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='4']"
|
||||
).attrib.get("level"),
|
||||
"3",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='4-5']/monitor[@vcpus='5']"
|
||||
).attrib.get("level"),
|
||||
"2",
|
||||
)
|
||||
self.assertNotEqual(setxml.find("./cputune/memorytune[@vcpus='0-2']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='0-2']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"60",
|
||||
)
|
||||
self.assertNotEqual(setxml.find("./cputune/memorytune[@vcpus='3-4']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"50",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='1']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"70",
|
||||
)
|
||||
|
||||
# test removing cputune attributes and sub elements
|
||||
cputune = {
|
||||
"shares": None,
|
||||
"period": 20000,
|
||||
"quota": None,
|
||||
"global_period": 5000,
|
||||
"global_quota": None,
|
||||
"emulator_period": 2000,
|
||||
"emulator_quota": -4,
|
||||
"iothread_period": None,
|
||||
"iothread_quota": -5,
|
||||
"vcpupin": {0: "1-4,^2", 2: "2,4"},
|
||||
"emulatorpin": None,
|
||||
"iothreadpin": {1: "5-6"},
|
||||
"vcpusched": [{"scheduler": "idle", "priority": 5, "vcpus": "1"}],
|
||||
"iothreadsched": None,
|
||||
"cachetune": {
|
||||
"0-3": {
|
||||
0: {"level": 4, "type": "data", "size": 7},
|
||||
"monitor": {"1-2": 11},
|
||||
},
|
||||
},
|
||||
"memorytune": {"3-4": {0: 37, 1: 73}},
|
||||
}
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": False,
|
||||
},
|
||||
virt.update("xml_with_cputune_params", cpu={"tuning": cputune}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("cputune").find("shares"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("period").text, "20000")
|
||||
self.assertEqual(setxml.find("cputune").find("quota"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("global_period").text, "5000")
|
||||
self.assertEqual(setxml.find("cputune").find("global_quota"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_period").text, "2000")
|
||||
self.assertEqual(setxml.find("cputune").find("emulator_quota").text, "-4")
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_period"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("iothread_quota").text, "-5")
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='0']").attrib.get("cpuset"),
|
||||
"1-4,^2",
|
||||
)
|
||||
self.assertEqual(setxml.find("cputune").find("vcpupin[@vcpu='1']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("vcpupin[@vcpu='2']").attrib.get("cpuset"),
|
||||
"2,4",
|
||||
)
|
||||
self.assertEqual(setxml.find("cputune").find("vcpupin[@vcpu='3']"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("emulatorpin"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune")
|
||||
.find("iothreadpin[@iothread='1']")
|
||||
.attrib.get("cpuset"),
|
||||
"5-6",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("cputune").find("iothreadpin[@iothread='2']"), None
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
s.get("vcpus"): {
|
||||
"scheduler": s.get("scheduler"),
|
||||
"priority": s.get("priority"),
|
||||
}
|
||||
for s in setxml.findall("cputune/vcpusched")
|
||||
},
|
||||
{"1": {"scheduler": "idle", "priority": "5"}},
|
||||
)
|
||||
self.assertEqual(setxml.find("cputune").find("iothreadsched"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']").attrib.get("vcpus"), "0-3"
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"size"
|
||||
),
|
||||
"7",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"level"
|
||||
),
|
||||
"4",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='0']").attrib.get(
|
||||
"type"
|
||||
),
|
||||
"data",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find(
|
||||
"./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='1-2']"
|
||||
).attrib.get("level"),
|
||||
"11",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/monitor[@vcpus='3-4']"), None
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/cachetune[@vcpus='0-3']/cache[@id='1']"), None
|
||||
)
|
||||
self.assertEqual(setxml.find("./cputune/cachetune[@vcpus='4-5']"), None)
|
||||
self.assertEqual(setxml.find("./cputune/memorytune[@vcpus='0-2']"), None)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='0']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"37",
|
||||
)
|
||||
self.assertEqual(
|
||||
setxml.find("./cputune/memorytune[@vcpus='3-4']/node[@id='1']").attrib.get(
|
||||
"bandwidth"
|
||||
),
|
||||
"73",
|
||||
)
|
||||
|
||||
cputune_subelement = {
|
||||
"vcpupin": None,
|
||||
"iothreadpin": None,
|
||||
"vcpusched": None,
|
||||
"iothreadsched": None,
|
||||
"cachetune": None,
|
||||
"memorytune": None,
|
||||
}
|
||||
|
||||
self.assertEqual(
|
||||
{
|
||||
"definition": True,
|
||||
"disk": {"attached": [], "detached": [], "updated": []},
|
||||
"interface": {"attached": [], "detached": []},
|
||||
"cpu": False,
|
||||
},
|
||||
virt.update("xml_with_cputune_params", cpu={"tuning": cputune_subelement}),
|
||||
)
|
||||
setxml = ET.fromstring(define_mock.call_args[0][0])
|
||||
self.assertEqual(setxml.find("cputune").find("vcpupin"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("iothreadpin"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("vcpusched"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("iothreadsched"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("cachetune"), None)
|
||||
self.assertEqual(setxml.find("cputune").find("memorytune"), None)
|
||||
|
||||
def test_handle_unit(self):
|
||||
"""
|
||||
Test regex function for handling units
|
||||
|
|
Loading…
Add table
Reference in a new issue