Change in vdsm[master]: Add man page for vdsm.conf
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: Add man page for vdsm.conf
......................................................................
Add man page for vdsm.conf
Show to user the vdsm.conf options.
Change-Id: Id8e5a47d484fa06070d4566a39cab8a7a53ea717
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M debian/vdsm.install
M vdsm.spec.in
M vdsm/Makefile.am
A vdsm/vdsm.conf.5
4 files changed, 400 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/91/22891/1
diff --git a/debian/vdsm.install b/debian/vdsm.install
index ef46ed3..0c2b137 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -31,6 +31,7 @@
./usr/libexec/vdsm/unpersist-vdsm-hook
./usr/libexec/vdsm/vdsm-gencerts.sh
./usr/libexec/vdsm/vdsmd_init_common.sh
+./usr/share/man/man5/vdsm.conf.5
./usr/share/man/man8/vdsmd.8
./usr/share/vdsm/API.py
./usr/share/vdsm/BindingJsonRpc.py
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 385a29b..364997b 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1014,6 +1014,7 @@
%{python_sitelib}/sos/plugins/vdsm.py*
/lib/udev/rules.d/12-vdsm-lvm.rules
/etc/security/limits.d/99-vdsm.conf
+%{_mandir}/man5/vdsm.conf.5*
%{_mandir}/man8/vdsmd.8*
%if 0%{?rhel}
%dir %{_localstatedir}/log/core
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 3834f55..1c1671e 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -89,6 +89,9 @@
vdsm-restore-net-config \
$(NULL)
+dist_man5_MANS = \
+ vdsm.conf.5
+
nodist_man8_MANS = \
vdsmd.8
diff --git a/vdsm/vdsm.conf.5 b/vdsm/vdsm.conf.5
new file mode 100644
index 0000000..98b4ccd
--- /dev/null
+++ b/vdsm/vdsm.conf.5
@@ -0,0 +1,395 @@
+.\"Copyright 2010-2013 Red Hat, Inc. and/or its affiliates.
+.\"
+.\"Licensed to you under the GNU General Public License as published by
+.\"the Free Software Foundation; either version 2 of the License, or
+.\"(at your option) any later version. See the files README and
+.\"LICENSE_GPL_v2 which accompany this distribution.
+.\"
+.\"
+.\" File Name macro definition plagiarized from bash.
+.\"
+.de FN
+\fI\|\\$1\|\fP
+..
+.TH VDSM.CONF 5 "December 6, 2013" "" ""
+.SH NAME
+vdsm.conf \- The configuration file for Virtual Desktops and Servers Manager (VDSM)
+.br
+.SH SYNOPSIS
+.PP
+The
+vdsm\&.conf
+file is a configuration file for VDSM.
+vdsm\&.conf
+contains runtime configuration information for the VDSM\&.
+The complete description of the file format and possible parameters held within are here for reference
+purposes\&.
+.SH "FILE FORMAT"
+.PP
+The file consists of sections and parameters\&. A section begins with the name of the section in square brackets and
+continues until the next section begins\&. Sections contain parameters of the form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIname\fR = \fIvalue \fR
+.fi
+.if n \{\
+.RE
+.\}
+
+.SH CONFIGURATION BY SECTION (EXAMPLE)
+.PP
+.B [vars]
+
+\fBcore_dump_enable\fR = true
+.br
+Enable core dump
+
+\fBhost_mem_reserve\fR = 256
+.br
+Reserves memory for the host to prevent VMs from using all the physical pages. The values are in Mbytes.
+
+\fBguest_ram_overhead\fR = 65
+
+\fBextra_mem_reserve\fR = 65
+.br
+Memory reserved for non-vds-administered programs.
+
+\fBfake_nics\fR
+.br
+Comma-separated list of fnmatch-patterns for dummy hosts nics to be shown to vdsm.
+
+\fBnic_model\fR = rtl8139,pv
+.br
+NIC model is rtl8139, ne2k_pci pv or any other valid device recognized by kvm/qemu if a coma separated list
+given then a NIC per device will be created.
+
+\fBmigration_timeout\fR = 300
+.br
+Maximum time the destination waits for migration to end. Source waits twice aslong (to avoid races)
+
+\fBmigration_listener_timeout\fR = 30
+.br
+Time to wait (in seconds) for migration destination to start listening before migration begins.
+
+\fBmigration_max_bandwidth\fR = 32
+.br
+Maximum bandwidth for migration, in MiBps, 0 means libvirt's default, since 0.10.x default in libvirt is unlimited
+
+\fBmigration_monitor_intervang\fR = 10
+.br
+How often (in seconds) should the monitor thread pulse, 0 means the thread is disabled
+
+\fBhidden_nics\fR = wlan*,usb*
+.br
+Comma-separated list of fnmatch-patterns for host nics to be hidden from vdsm.
+
+\fBdefault_bridge\fR = engine
+.br
+Default bridge
+
+\fBmigration_downtime\fR = 500
+.br
+Maxmium allowed downtime for live migration in milliseconds (anything below 100ms is ignored) if you do not care about
+liveness of migration, set to a very high value, such as 600000.
+
+\fBmigration_downtime_steps\fR = 10
+.br
+Incremental steps used to reach migration_downtime
+
+\fBmax_outgoing_migrations\fR = 3
+.br
+Maximum concurrent outgoing migrations
+
+\fBsys_shutdown_timeout\fR = 10
+.br
+Destroy and shutdown timeouts (in sec) before completing the action.
+
+\fBuser_shutdown_timeout\fR = 30
+.br
+Grace period (seconds) to let guest user close his applications before shutdown.
+
+\fBguest_agent_timeout\fR = 30
+.br
+Time (in sec) to wait for guest agent.
+
+\fBvm_command_timeout\fR = 60
+.br
+Time to wait (in seconds) for vm to respond to a monitor command, 30 secs is a nice default. Set to 300 if the vm is expected to freeze during cluster failover.
+
+\fBvm_watermark_interval\fR = 2
+.br
+How often should we sample each vm for statistics (seconds).
+
+\fBvm_sample_cpu_interval\fR = 15
+.br
+Interval to collect sampe from CPU
+
+\fBvm_sample_cpu_window\fR = 2
+.br
+Interval to collect from CPU window
+
+\fBvm_sample_disk_interval\fR = 60
+.br
+Interval to collect sample from disk
+
+\fBvm_sample_disk_window\fR = 2
+.br
+Interval to collect disk window
+
+\fBvm_sample_disk_latency_interval\fR = 60
+.br
+Interval to collect disk latency
+
+\fBvm_sample_disk_latency_window\fR = 2
+.br
+Interval to collect disk latency window
+
+\fBvm_sample_net_interval\fR = 5
+.br
+Interval to collect sample from net
+
+\fBvm_sample_net_window\fR = 2
+.br
+Interval to collect sample from net window
+
+\fBtrust_store_path\fR = /etc/pki/vdsm
+.br
+Where the certificates and keys are situated
+
+\fBssl\fR = true
+.br
+Whether to use ssl encryption and authentication.
+
+\fBvds_responsiveness_timeout\fR = 60
+.br
+Responsiveness timeout
+
+\fBvdsm_nice\fR = -5
+.br
+Set vdsm scheduling priority
+
+\fBqemu_drive_cache\fR = none
+.br
+Qemu drive cache
+
+\fBfake_kvm_support\fR = false
+.br
+Emulate kvm support
+
+\fBxmlrpc_enable\fR = true
+.br
+Enable the xmlrpc server
+
+\fBjsonrpc_enable\fR = true
+.br
+Enable the JSON RPC server
+
+\fBreport_host_threads_as_cores\fR = false
+.br
+Count each cpu hyperthread as an individual core
+
+\fBlibvirt_env_variable_log_filters\fR
+.br
+Specify the log filters to track libvirt calls
+
+\fBlibvirt_env_variable_log_outputs\fR
+.br
+Specify the output to track libvirt calls
+
+.B [ksm]
+.br
+\fBksm_monitor_thread\fR = true
+.br
+KSM Monitor
+
+.br
+.B [mom]
+.br
+\fBconf\fR = /etc/vdsm/mom.conf
+.br
+Mom conf file
+.br
+
+.B [irs]
+.br
+\fBirs_enable\fR = true
+.br
+Enable IRS
+
+\fBrepository\fR = path to repository
+.br
+Image Repository
+
+\fBhsm_tasks\fR = (repository)/hsm
+.br
+hsm dir
+
+\fBimages\fR = images/
+.br
+images dir
+
+\fBirsd\fR = (images)/irsd
+.br
+irsd dir
+
+\fBimages_check_times\fR = 0
+.br
+Image repository check period (seconds).
+
+\fBvolume_utilization_percent\fR = 50
+.br
+Volume utilization percent
+
+\fBvolume_utilization_chunk_mb\fR = 1024
+.br
+Volume utilization chunk of mb
+
+\fBvol_size_sample_interval\fR = 60
+.br
+How often should the volume size be checked (seconds).
+
+\fBsd_validate_timeout\fR = 80
+.br
+Storage domain validate timeout, the maximum number of seconds to wait until all the domains will be validated.
+
+\fBscsi_rescan_minimal_timeout\fR = 2
+.br
+The minimum number of seconds to wait for scsi scan to return.
+
+\fBscsi_rescan_maximal_timeout\fR = 30
+.br
+The maximal number of seconds to wait for scsi scan to return.
+
+\fBsd_health_check_delay\fR = 10
+.br
+Storage domain health check delay, the amount of seconds to wait between two successive run of the domain health check.
+
+\fBnfs_mount_options\fR = soft,nosharecache
+.br
+NFS mount options, comma-separated list (NB: no white space allowed!)
+
+\fBpools_data_dir\fR = /var/run/vdsm/pools
+.br
+Pool data dir
+
+\fBvol_extend_policy\fR = ON
+.br
+Volume extend policy
+
+\fBlock_util_path\fR = /usr/libexec/vdsm
+.br
+Block util path
+
+\fBlock_cmd\fR = spmprotect.sh
+.br
+The lock command
+
+\fBfree_lock_cmd\fR = spmstop.sh
+.br
+The free lock command
+
+\fBthread_pool_size\fR = 10
+.br
+Thread pool size
+
+\fBmax_tasks\fR = 500
+.br
+Number max of tasks
+
+\fBlvm_dev_whitelist\fR
+.br
+LVM whitelist
+
+\fBmd_backup_versions\fR = 30
+.br
+Versions of backup
+
+\fBmd_backup_dir\fR = /var/log/vdsm/backup
+.br
+Backup dir
+
+\fBmaximum_allowed_pvs\fR = 8
+.br
+The number of PVs per VG has a hard-coded limit of 10.
+
+\fBrepo_stats_cache_refresh_timeout\fR = 300
+.br
+Repo stats cache refresh
+
+\fBtask_resource_default_timeout\fR = 120000
+.br
+Task resource default timeout
+
+\fBprepare_image_timeout\fR = 600000
+.br
+Prepare image timeout
+
+\fBgc_blocker_force_collect_interval\fR = 60
+.br
+Force collect interval
+
+\fBmaximum_domains_in_pool\fR = 100
+.br
+Process pool configuration.
+
+\fBprocess_pool_size\fR = 100
+.br
+Pool size
+
+\fBprocess_pool_timeout\fR = 60
+.br
+Pool timeout
+
+\fBprocess_pool_grace_period\fR = 2
+.br
+Pool grace period
+
+\fBprocess_pool_max_slots_per_domain\fR = 10
+.br
+Max slots per domain
+
+\fBiscsi_default_ifaces\fR = default
+.br
+Comma seperated ifaces to connect with. i.e. iser,default
+
+\fBuse_volume_leases\fR = false
+.br
+Whether to use the volume leases or not.
+
+.B [address]
+.br
+\fBmanagement_port\fR = 54321
+.br
+Port on which the vdsmd server listens to network clients
+
+\fBss_pool_timeoutjson_port\fR = 4044
+.br
+Port on which the vdsmd Json RPC server listens to network clients
+
+\fBmanagement_ip\fR
+.br
+IP address of management server
+
+\fBguests_gateway_ip\fR
+.br
+Guests gateway IP address
+
+.SH "SEE ALSO"
+.PP
+
+\fBvdsClient\fR(1),
+\fBvdsmd\fR(8)
+
+.SH AUTHOR
+VDSM was written by Ayal Baron, Barak Azulay, Cyril Plisko, Dan Kenigsberg,
+Doron Fediuck, Igor Lvovsky, Saggi Mizrahi, Shahar Frank, Simon Grinberg and
+others.
+
+.SH BUGS
+Report bugs to <http://bugzilla.redhat.com>
+
+.SH COPYRIGHT
+Copyright 2010-2013 Red Hat, Inc. License GPLv2: GNU GPL Version 2 <http://gnu.org/licenses/gpl.html>.
--
To view, visit http://gerrit.ovirt.org/22891
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id8e5a47d484fa06070d4566a39cab8a7a53ea717
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
9 years, 6 months
Change in vdsm[master]: tests: sampling: add initial HostStatsThread tests
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: tests: sampling: add initial HostStatsThread tests
......................................................................
tests: sampling: add initial HostStatsThread tests
This patch adds a unit test to HostStatsThread.
Change-Id: Ic4e5765364cf46e1ebfaac72aa5f75c80e83779e
Relates-To: https://bugzilla.redhat.com/1113948
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M tests/samplingTests.py
M vdsm/virt/sampling.py
2 files changed, 37 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/66/29566/1
diff --git a/tests/samplingTests.py b/tests/samplingTests.py
index 2ff703e..5126f69 100644
--- a/tests/samplingTests.py
+++ b/tests/samplingTests.py
@@ -21,6 +21,8 @@
import os
import tempfile
import shutil
+import threading
+import time
from vdsm import ipwrapper
import virt.sampling as sampling
@@ -111,3 +113,37 @@
s1 = sampling.InterfaceSample(lo)
s1.operstate = 'x'
self.assertEquals('operstate:x', s1.connlog_diff(s0))
+
+
+class HostStatsThread(TestCaseBase):
+ FAILED_SAMPLE = 3 # random 'small' value
+ STOP_SAMPLE = 6 # ditto
+
+ def setUp(self):
+ self._hs = None
+ self._sampleCount = 0
+ self._samplingDone = threading.Event()
+
+ def testContinueWithErrors(self):
+ """
+ bz1113948: do not give up on errors != TimeoutError
+ """
+ def WrapHostSample(pid):
+ self._sampleCount += 1
+ if self._sampleCount == self.FAILED_SAMPLE:
+ raise ValueError
+ if self._sampleCount == self.STOP_SAMPLE:
+ self._hs.stop()
+ self._samplingDone.set()
+ return None # sampling.HostSample(pid)
+
+ def nosleep(seconds):
+ pass
+
+ with MonkeyPatchScope([(sampling, 'HostSample', WrapHostSample),
+ (time, 'sleep', nosleep)]):
+ self._hs = sampling.HostStatsThread(self.log)
+ self._hs.start()
+ self._samplingDone.wait()
+ self._hs.stop()
+ self.assertTrue(self._sampleCount >= self.STOP_SAMPLE)
diff --git a/vdsm/virt/sampling.py b/vdsm/virt/sampling.py
index 5f04f27..ccb0672 100644
--- a/vdsm/virt/sampling.py
+++ b/vdsm/virt/sampling.py
@@ -507,7 +507,7 @@
exc_info=True)
except Exception:
self._log.exception("Error while sampling stats")
- self._stopEvent.wait(self.SAMPLE_INTERVAL_SEC)
+ time.sleep(self.SAMPLE_INTERVAL_SEC)
@utils.memoized
def _boot_time(self):
--
To view, visit http://gerrit.ovirt.org/29566
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic4e5765364cf46e1ebfaac72aa5f75c80e83779e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
9 years, 6 months
Change in vdsm[master]: unit_tests: Make run_tests_local.sh not be a generated file
by asegurap@redhat.com
Antoni Segura Puimedon has uploaded a new change for review.
Change subject: unit_tests: Make run_tests_local.sh not be a generated file
......................................................................
unit_tests: Make run_tests_local.sh not be a generated file
It is perfectly possible to simplify run_tests_local.sh.in so that
it does not use macros and this at the same time will allow for
testing subdirectories to use it.
Change-Id: Ie20647b9a7b447b8ed4082f7cefab2146150594e
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
A tests/run_tests_local.sh
D tests/run_tests_local.sh.in
2 files changed, 15 insertions(+), 10 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/27632/1
diff --git a/tests/run_tests_local.sh b/tests/run_tests_local.sh
new file mode 100755
index 0000000..b282c10
--- /dev/null
+++ b/tests/run_tests_local.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+if [ -z "$PYTHON_EXE" ]; then
+ ENV_BIN="/usr/bin/env"
+ PYTHON_EXE="python2"
+fi
+
+# The following line is taken from http://stackoverflow.com/a/246128/206009
+# it sets DIR to the path of the directory that contains this bash script
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+if [ ! -f "$DIR/jsonrpc-tests.server.crt" ] || [ ! -f "$DIR/jsonrpc-tests.server.csr" ] || [ ! -f "$DIR/jsonrpc-tests.server.key" ]; then
+ $DIR/makecert.sh
+fi
+
+PYTHONDONTWRITEBYTECODE=1 LC_ALL=C PYTHONPATH="$DIR/../lib:$DIR/../vdsm:$DIR/../client:$DIR/../vdsm_api:$PYTHONPATH" $ENV_BIN "$PYTHON_EXE" $DIR/testrunner.py --local-modules $@
diff --git a/tests/run_tests_local.sh.in b/tests/run_tests_local.sh.in
deleted file mode 100644
index 0a229c0..0000000
--- a/tests/run_tests_local.sh.in
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-if [ -z "$PYTHON_EXE" ]; then
- PYTHON_EXE="@PYTHON@"
-fi
-
-if [ ! -f @top_srcdir(a)/tests/jsonrpc-tests.server.crt ] || [ ! -f @top_srcdir(a)/tests/jsonrpc-tests.server.csr ] || [ ! -f @top_srcdir(a)/tests/jsonrpc-tests.server.key ]; then
- @top_srcdir(a)/tests/makecert.sh
-fi
-
-PYTHONDONTWRITEBYTECODE=1 LC_ALL=C PYTHONPATH="@top_srcdir@/lib:@top_srcdir@/vdsm:@top_srcdir@/client:@top_srcdir@/vdsm_api:$PYTHONPATH" "$PYTHON_EXE" @top_srcdir(a)/tests/testrunner.py --local-modules $@
--
To view, visit http://gerrit.ovirt.org/27632
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie20647b9a7b447b8ed4082f7cefab2146150594e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: Change method names in vmtune.py to the PEP8 style
by Martin Sivak
Hello Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30078
to review the following change.
Change subject: Change method names in vmtune.py to the PEP8 style
......................................................................
Change method names in vmtune.py to the PEP8 style
Change-Id: Ib5e9dcaf393ebafe56f6bc78cc9cb02d37a257ae
Signed-off-by: Martin Sivak <msivak(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/29929
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/vmTests.py
M vdsm/virt/vm.py
M vdsm/virt/vmtune.py
3 files changed, 25 insertions(+), 25 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/78/30078/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 498aeac..999de1b 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -30,7 +30,7 @@
from virt import vm
from virt import vmexitreason
-from virt.vmtune import ioTuneMerge, ioTuneDomToValues, ioTuneToDom
+from virt.vmtune import io_tune_merge, io_tune_dom_to_values, io_tune_to_dom
from vdsm import constants
from vdsm import define
from testrunner import VdsmTestCase as TestCaseBase
@@ -984,8 +984,8 @@
}
}
- dom = ioTuneToDom(ioTuneValues)
- parsed = ioTuneDomToValues(dom)
+ dom = io_tune_to_dom(ioTuneValues)
+ parsed = io_tune_dom_to_values(dom)
self.assertEqual(ioTuneValues, parsed)
@@ -1037,7 +1037,7 @@
}
}
- ioTuneMerged = ioTuneMerge(ioTuneValues1, ioTuneValues2)
+ ioTuneMerged = io_tune_merge(ioTuneValues1, ioTuneValues2)
self.assertEqual(ioTuneMerged, ioTuneExpectedValues)
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 536c146..9581357 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -64,8 +64,8 @@
from . import sampling
from . import vmexitreason
from . import vmstatus
-from .vmtune import updateIoTuneDom, collectInnerElements
-from .vmtune import ioTuneValuesToDom, ioTuneDomToValues
+from .vmtune import update_io_tune_dom, collect_inner_elements
+from .vmtune import io_tune_values_to_dom, io_tune_dom_to_values
from .utils import XMLElement
from vmpowerdown import VmShutdown, VmReboot
@@ -3689,7 +3689,7 @@
qos.appendChild(ioTuneElement)
metadata_modified = True
- if updateIoTuneDom(ioTuneList[0], params["ioTune"]) > 0:
+ if update_io_tune_dom(ioTuneList[0], params["ioTune"]) > 0:
metadata_modified = True
del params['ioTune']
@@ -3761,7 +3761,7 @@
return []
for device in ioTuneList[0].getElementsByTagName("device"):
- tunables.append(ioTuneDomToValues(device))
+ tunables.append(io_tune_dom_to_values(device))
return tunables
@@ -3784,7 +3784,7 @@
io_dom_list = dom.getElementsByTagName("iotune")
old_io_tune = {}
if io_dom_list:
- collectInnerElements(io_dom_list[0], old_io_tune)
+ collect_inner_elements(io_dom_list[0], old_io_tune)
old_io_tune.update(io_tune)
io_tune = old_io_tune
@@ -3813,7 +3813,7 @@
if io_dom_list:
dom.removeChild(io_dom_list[0])
io_dom = XMLElement("iotune")
- ioTuneValuesToDom(io_tune, io_dom)
+ io_tune_values_to_dom(io_tune, io_dom)
dom.appendChild(io_dom)
found_device.specParams['ioTune'] = io_tune
diff --git a/vdsm/virt/vmtune.py b/vdsm/virt/vmtune.py
index 06558fe..ed5d575 100644
--- a/vdsm/virt/vmtune.py
+++ b/vdsm/virt/vmtune.py
@@ -27,7 +27,7 @@
log = logging.getLogger(__name__)
-def ioTuneValuesToDom(values, dom):
+def io_tune_values_to_dom(values, dom):
"""
Create a DOM representation of the passed iotune values and
attach it to the dom object in the form of nodes.
@@ -46,7 +46,7 @@
dom.appendChild(el)
-def collectInnerElements(el, d):
+def collect_inner_elements(el, d):
"""
This helper method collects all nodes in el and adds them
to dictionary d.
@@ -64,7 +64,7 @@
log.exception("Invalid value for %s", chel.localName)
-def ioTuneDomToValues(dom):
+def io_tune_dom_to_values(dom):
"""
This method converts the VmDiskDeviceTuneLimits structure from its
XML representation to the dictionary representation.
@@ -83,18 +83,18 @@
els = dom.getElementsByTagName("guaranteed")
if els:
values["guaranteed"] = {}
- collectInnerElements(els[0], values["guaranteed"])
+ collect_inner_elements(els[0], values["guaranteed"])
els = dom.getElementsByTagName("maximum")
if els:
values["maximum"] = {}
for chel in els[0].childNodes:
- collectInnerElements(els[0], values["maximum"])
+ collect_inner_elements(els[0], values["maximum"])
return values
-def ioTuneToDom(tune):
+def io_tune_to_dom(tune):
"""
This method converts the VmDiskDeviceTuneLimits structure from the
dictionary representation to the XML representation.
@@ -113,17 +113,17 @@
if "maximum" in tune:
maximum = XMLElement("maximum")
device.appendChild(maximum)
- ioTuneValuesToDom(tune["maximum"], maximum)
+ io_tune_values_to_dom(tune["maximum"], maximum)
if "guaranteed" in tune:
guaranteed = XMLElement("guaranteed")
device.appendChild(guaranteed)
- ioTuneValuesToDom(tune["guaranteed"], guaranteed)
+ io_tune_values_to_dom(tune["guaranteed"], guaranteed)
return device
-def ioTuneMerge(old, new):
+def io_tune_merge(old, new):
"""
Merge two VmDiskDeviceTuneLimits structures in their dictionary form
and return the new iotune setting.
@@ -152,7 +152,7 @@
return result
-def createDeviceIndex(ioTune):
+def create_device_index(ioTune):
"""
Create by name / by path dictionaries from the XML representation.
Returns a tuple (by_name, by_path) where the items are the respective
@@ -176,7 +176,7 @@
return ioTuneByName, ioTuneByPath
-def updateIoTuneDom(ioTune, tunables):
+def update_io_tune_dom(ioTune, tunables):
"""
This method takes a list of VmDiskDeviceTuneLimits objects and applies
the changes to the XML element representing the current iotune settings,
@@ -191,7 +191,7 @@
count = 0
# Get all existing ioTune records and create name/path index
- ioTuneByName, ioTuneByPath = createDeviceIndex(ioTune)
+ ioTuneByName, ioTuneByPath = create_device_index(ioTune)
for limit_object in tunables:
old_tune = None
@@ -205,10 +205,10 @@
ioTune.removeChild(old_tune)
if old_tune is not None:
- old_object = ioTuneDomToValues(old_tune)
- limit_object = ioTuneMerge(old_object, limit_object)
+ old_object = io_tune_dom_to_values(old_tune)
+ limit_object = io_tune_merge(old_object, limit_object)
- new_tune = ioTuneToDom(limit_object)
+ new_tune = io_tune_to_dom(limit_object)
ioTune.appendChild(new_tune)
count += 1
--
To view, visit http://gerrit.ovirt.org/30078
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib5e9dcaf393ebafe56f6bc78cc9cb02d37a257ae
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: Add API.VM.getIoTunePolicy
by Martin Sivak
Hello Piotr Kliczewski, Dan Kenigsberg, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30077
to review the following change.
Change subject: Add API.VM.getIoTunePolicy
......................................................................
Add API.VM.getIoTunePolicy
This method can be used by MoM to retrieve the current ioTune
boundaries from the domain xml metadata section.
Change-Id: Ib7983d91fe4b90c5b85c986c2b5a9a1931cfdc42
Signed-off-by: Martin Sivak <msivak(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/28896
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/vmTests.py
M vdsm/API.py
M vdsm/rpc/Bridge.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/vm.py
5 files changed, 73 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/77/30077/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 11a256d..498aeac 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -1150,6 +1150,41 @@
self.maxDiff = None
self.assertEqual(expected_xml, self._xml_sanitizer(dom._metadata))
+ def testGetIoTune(self):
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ dom._metadata = """
+ <qos>
+ <vcpuLimit>999</vcpuLimit>
+ <ioTune>
+ <device name='test-device-by-name'>
+ <maximum>
+ <totalBytes>9999</totalBytes>
+ </maximum>
+ </device>
+ <device name='other-device'>
+ <guaranteed>
+ <totalBytes>9999</totalBytes>
+ </guaranteed>
+ </device>
+ </ioTune>
+ </qos>
+ """
+ machine._dom = dom
+
+ tunables = machine.getIoTunePolicy()
+ expected = [
+ {'name': u'test-device-by-name',
+ 'maximum': {
+ u'totalBytes': 9999
+ }},
+ {'name': u'other-device',
+ 'guaranteed': {
+ u'totalBytes': 9999
+ }}
+ ]
+ self.assertEqual(tunables, expected)
+
def testSetIoTune(self):
drives = [
diff --git a/vdsm/API.py b/vdsm/API.py
index 509fa9d..6feccf6 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -714,6 +714,12 @@
return errCode['noVM']
return v.setIoTune(tunables)
+ def getIoTunePolicy(self):
+ v = self._cif.vmContainer.get(self._UUID)
+ if not v:
+ return errCode['noVM']
+ return v.getIoTunePolicy()
+
def setCpuTunePeriod(self, period):
v = self._cif.vmContainer.get(self._UUID)
if not v:
@@ -1194,7 +1200,7 @@
return {'status': {'code': 0, 'message': message},
'power': power}
threading.Thread(target=fence, args=(script, inp)).start()
- return {'status': doneCode, 'power': 'unknown'}
+ return {'status': doneCode}
def ping(self):
"Ping the server. Useful for tests"
diff --git a/vdsm/rpc/Bridge.py b/vdsm/rpc/Bridge.py
index 4246116..d017b07 100644
--- a/vdsm/rpc/Bridge.py
+++ b/vdsm/rpc/Bridge.py
@@ -409,6 +409,7 @@
'VM_mergeStatus': {'ret': 'mergeStatus'},
'VM_migrationCreate': {'ret': VM_migrationCreate_Ret},
'VM_setNumberOfCpus': {'ret': 'vmList'},
+ 'VM_getIoTunePolicy': {'ret': 'ioTunePolicyList'},
'Volume_copy': {'ret': 'uuid'},
'Volume_create': {'ret': 'uuid'},
'Volume_delete': {'ret': 'uuid'},
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 31b1873..c89ccd5 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -7514,6 +7514,23 @@
'returns': 'TaskStatus'}
##
+# @VM.getIoTunePolicy:
+#
+# Gets the ioTune policy settings for block devices
+#
+# @vmID: The UUID of the VM
+#
+# Returns:
+# list of VmDiskDeviceTuneParams objects describing
+# the current settings
+#
+# Since: 4.15.0
+##
+{'command': {'class': 'VM', 'name': 'getIoTunePolicy'},
+ 'data': {'vmID': 'UUID'},
+ 'returns': ['VmDiskDeviceTuneParams']}
+
+##
# @VM.setCpuTuneQuota:
#
# Set the vCpu quota tune parameter to the VM
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 80ede4c..536c146 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -65,7 +65,7 @@
from . import vmexitreason
from . import vmstatus
from .vmtune import updateIoTuneDom, collectInnerElements
-from .vmtune import ioTuneValuesToDom
+from .vmtune import ioTuneValuesToDom, ioTuneDomToValues
from .utils import XMLElement
from vmpowerdown import VmShutdown, VmReboot
@@ -3753,6 +3753,18 @@
else:
return None
+ def getIoTunePolicy(self):
+ tunables = []
+ qos = self._getVmPolicy()
+ ioTuneList = qos.getElementsByTagName("ioTune")
+ if not ioTuneList or not ioTuneList[0].hasChildNodes():
+ return []
+
+ for device in ioTuneList[0].getElementsByTagName("device"):
+ tunables.append(ioTuneDomToValues(device))
+
+ return tunables
+
def setIoTune(self, tunables):
for io_tune_change in tunables:
device_name = io_tune_change.get('name', None)
--
To view, visit http://gerrit.ovirt.org/30077
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib7983d91fe4b90c5b85c986c2b5a9a1931cfdc42
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: Add API.VM.setIoTune
by Martin Sivak
Hello Dan Kenigsberg, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30076
to review the following change.
Change subject: Add API.VM.setIoTune
......................................................................
Add API.VM.setIoTune
This allows MoM (and the engine if necessary) to set the iotune
limits for disk devices.
Change-Id: I0bd48f13311ad2efc4241117a777ca3400c259ea
Signed-off-by: Martin Sivak <msivak(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/28714
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M lib/vdsm/define.py
M tests/vmTests.py
M vdsm/API.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/vm.py
5 files changed, 173 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/76/30076/1
diff --git a/lib/vdsm/define.py b/lib/vdsm/define.py
index 4b25f89..34f423a 100644
--- a/lib/vdsm/define.py
+++ b/lib/vdsm/define.py
@@ -144,6 +144,9 @@
'updateVmPolicyErr': {'status': {
'code': 63,
'message': 'Failed to update VM SLA policy'}},
+ 'updateIoTuneErr': {'status': {
+ 'code': 64,
+ 'message': 'Failed to update ioTune values'}},
'recovery': {'status': {
'code': 99,
'message': 'Recovering from crash or Initializing'}},
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 5c3d445..11a256d 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -60,6 +60,7 @@
self.devXml = ''
self._virtError = virtError
self._metadata = ""
+ self._io_tune = {}
def _failIfRequested(self):
if self._virtError != libvirt.VIR_ERR_OK:
@@ -94,6 +95,10 @@
def schedulerParameters(self):
return {'vcpu_quota': vm._NO_CPU_QUOTA,
'vcpu_period': vm._NO_CPU_PERIOD}
+
+ def setBlockIoTune(self, name, io_tune, flags):
+ self._io_tune[name] = io_tune
+ return 1
class TestVm(TestCaseBase):
@@ -1145,6 +1150,76 @@
self.maxDiff = None
self.assertEqual(expected_xml, self._xml_sanitizer(dom._metadata))
+ def testSetIoTune(self):
+
+ drives = [
+ vm.Drive({
+ "specParams": {
+ "ioTune": {
+ "total_bytes_sec": 9999,
+ "total_iops_sec": 9999}
+ }},
+ log=self.log,
+ index=0,
+ device="hdd",
+ path="/dev/dummy",
+ type=vm.DISK_DEVICES,
+ iface="ide")
+ ]
+
+ # Make the drive look like a VDSM volume
+ required = ('domainID', 'imageID', 'poolID', 'volumeID')
+ for p in required:
+ setattr(drives[0], p, "1")
+ drives[0]._blockDev = True
+
+ tunables = [
+ {
+ "name": drives[0].name,
+ "ioTune": {
+ "write_bytes_sec": 1,
+ "total_bytes_sec": 0,
+ "read_bytes_sec": 2
+ }
+ }
+ ]
+
+ expected_io_tune = {
+ drives[0].name: {
+ "write_bytes_sec": 1,
+ "total_bytes_sec": 0,
+ "read_bytes_sec": 2
+ }
+ }
+
+ expected_xml = """
+ <disk device="hdd" snapshot="no" type="block">
+ <source dev="/dev/dummy"/>
+ <target bus="ide" dev="hda"/>
+ <serial></serial>
+ <iotune>
+ <read_bytes_sec>2</read_bytes_sec>
+ <write_bytes_sec>1</write_bytes_sec>
+ <total_bytes_sec>0</total_bytes_sec>
+ </iotune>
+ </disk>"""
+
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ machine._dom = dom
+ for drive in drives:
+ machine._devices[drive.type].append(drive)
+
+ machine.setIoTune(tunables)
+
+ self.assertEqual(expected_io_tune, dom._io_tune)
+
+ # Test that caches were properly updated
+ self.assertEqual(drives[0].specParams["ioTune"],
+ expected_io_tune[drives[0].name])
+ self.assertEqual(self._xml_sanitizer(drives[0]._deviceXML),
+ self._xml_sanitizer(expected_xml))
+
class FakeGuestAgent(object):
def getGuestInfo(self):
diff --git a/vdsm/API.py b/vdsm/API.py
index ace68d1..509fa9d 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -708,6 +708,12 @@
return errCode['noVM']
return v.setCpuTuneQuota(quota)
+ def setIoTune(self, tunables):
+ v = self._cif.vmContainer.get(self._UUID)
+ if not v:
+ return errCode['noVM']
+ return v.setIoTune(tunables)
+
def setCpuTunePeriod(self, period):
v = self._cif.vmContainer.get(self._UUID)
if not v:
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 47124af..31b1873 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -7496,6 +7496,24 @@
'returns': 'VmDefinition'}
##
+# @VM.setIoTune:
+#
+# Sets the ioTune parameters for block devices
+#
+# @vmID: The UUID of the VM
+#
+# @tunables: list of VmDiskDeviceTuneParams objects
+# describing the new settings
+# Returns:
+# Status code
+#
+# Since: 4.15.0
+##
+{'command': {'class': 'VM', 'name': 'setIoTune'},
+ 'data': {'vmID': 'UUID', 'tunables': ['VmDiskDeviceTuneParams']},
+ 'returns': 'TaskStatus'}
+
+##
# @VM.setCpuTuneQuota:
#
# Set the vCpu quota tune parameter to the VM
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index b3dd8f2..80ede4c 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -64,7 +64,8 @@
from . import sampling
from . import vmexitreason
from . import vmstatus
-from .vmtune import updateIoTuneDom
+from .vmtune import updateIoTuneDom, collectInnerElements
+from .vmtune import ioTuneValuesToDom
from .utils import XMLElement
from vmpowerdown import VmShutdown, VmReboot
@@ -3743,6 +3744,75 @@
metadata = xml.dom.minidom.parseString(metadata_xml)
return metadata.getElementsByTagName("qos")[0]
+ def _findDeviceByNameOrPath(self, device_name, device_path):
+ for device in self._devices[DISK_DEVICES]:
+ if ((device.name == device_name
+ or ("path" in device and device["path"] == device_path))
+ and isVdsmImage(device)):
+ return device
+ else:
+ return None
+
+ def setIoTune(self, tunables):
+ for io_tune_change in tunables:
+ device_name = io_tune_change.get('name', None)
+ device_path = io_tune_change.get('path', None)
+ io_tune = io_tune_change['ioTune']
+
+ # Find the proper device object
+ found_device = self._findDeviceByNameOrPath(device_name,
+ device_path)
+ if found_device is None:
+ return self._reportError(
+ key='updateIoTuneErr',
+ msg="Device {} not found".format(device_name))
+
+ # Merge the update with current values
+ dom = found_device.getXML()
+ io_dom_list = dom.getElementsByTagName("iotune")
+ old_io_tune = {}
+ if io_dom_list:
+ collectInnerElements(io_dom_list[0], old_io_tune)
+ old_io_tune.update(io_tune)
+ io_tune = old_io_tune
+
+ # Verify the ioTune params
+ try:
+ found_device._validateIoTuneParams(io_tune)
+ except ValueError:
+ return self._reportException(key='updateIoTuneErr',
+ msg='Invalid ioTune value')
+
+ try:
+ self._dom.setBlockIoTune(found_device.name, io_tune,
+ libvirt.VIR_DOMAIN_AFFECT_LIVE)
+ except libvirt.libvirtError as e:
+ self.log.exception("setVmIoTune failed")
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return errCode['noVM']
+ else:
+ return self._reportError(key='updateIoTuneErr',
+ msg=e.message)
+
+ # Update both the ioTune arguments and device xml DOM
+ # so we are still up-to-date
+ # TODO: improve once libvirt gets support for iotune events
+ # see https://bugzilla.redhat.com/show_bug.cgi?id=1114492
+ if io_dom_list:
+ dom.removeChild(io_dom_list[0])
+ io_dom = XMLElement("iotune")
+ ioTuneValuesToDom(io_tune, io_dom)
+ dom.appendChild(io_dom)
+ found_device.specParams['ioTune'] = io_tune
+
+ # Make sure the cached XML representation is valid as well
+ xml = found_device.getXML().toprettyxml(encoding='utf-8')
+ self.log.debug("New device XML for %s: %s",
+ found_device.name, xml)
+ found_device._deviceXML = xml
+
+ return {'status': doneCode}
+
def _createTransientDisk(self, diskParams):
if diskParams.get('shared', None) != DRIVE_SHARED_TYPE.TRANSIENT:
return
--
To view, visit http://gerrit.ovirt.org/30076
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0bd48f13311ad2efc4241117a777ca3400c259ea
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: Add setIoTune and getIoTunePolicy to the xml-rpc API
by Martin Sivak
Hello Nir Soffer, Dan Kenigsberg, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30075
to review the following change.
Change subject: Add setIoTune and getIoTunePolicy to the xml-rpc API
......................................................................
Add setIoTune and getIoTunePolicy to the xml-rpc API
Change-Id: I1cac66eb93b3702b6274b3dfd0816158532effc3
Signed-off-by: Martin Sivak <msivak(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/29115
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/rpc/BindingXMLRPC.py
1 file changed, 11 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/30075/1
diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index 525fcc0..59adfca 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -459,6 +459,14 @@
api = API.Global()
return api.getAllVmStats()
+ def vmGetIoTunePolicy(self, vmId):
+ vm = API.VM(vmId)
+ return vm.getIoTunePolicy()
+
+ def vmSetIoTune(self, vmId, tunables):
+ vm = API.VM(vmId)
+ return vm.setIoTune(tunables)
+
def vmMigrationCreate(self, params):
vm = API.VM(params['vmId'])
return vm.migrationCreate(params)
@@ -987,7 +995,9 @@
(self.vmUpdateDevice, 'vmUpdateDevice'),
(self.vmSetNumberOfCpus, 'setNumberOfCpus'),
(self.merge, 'merge'),
- (self.vmUpdateVmPolicy, 'updateVmPolicy'))
+ (self.vmUpdateVmPolicy, 'updateVmPolicy'),
+ (self.vmSetIoTune, 'setIoTune'),
+ (self.vmGetIoTunePolicy, 'getIoTunePolicy'))
def getIrsMethods(self):
return ((self.domainActivate, 'activateStorageDomain'),
--
To view, visit http://gerrit.ovirt.org/30075
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1cac66eb93b3702b6274b3dfd0816158532effc3
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: Add IO tunables support to updateVmPolicy
by Martin Sivak
Hello Dan Kenigsberg,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30074
to review the following change.
Change subject: Add IO tunables support to updateVmPolicy
......................................................................
Add IO tunables support to updateVmPolicy
This allows the engine to set the hard and soft limits for IO.
MoM will then use those limits as a boundaries for dynamic
iotune updates.
Change-Id: I4ed108fbb2bf9d9af80577b2905242bf9f8c4221
Signed-off-by: Martin Sivak <msivak(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/28715
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/vmTests.py
M vdsm.spec.in
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/Makefile.am
M vdsm/virt/vm.py
A vdsm/virt/vmtune.py
6 files changed, 588 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/30074/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 02b1339..5c3d445 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -30,6 +30,7 @@
from virt import vm
from virt import vmexitreason
+from virt.vmtune import ioTuneMerge, ioTuneDomToValues, ioTuneToDom
from vdsm import constants
from vdsm import define
from testrunner import VdsmTestCase as TestCaseBase
@@ -58,6 +59,7 @@
self._xml = xml
self.devXml = ''
self._virtError = virtError
+ self._metadata = ""
def _failIfRequested(self):
if self._virtError != libvirt.VIR_ERR_OK:
@@ -79,7 +81,15 @@
def metadata(self, type, uri, flags):
self._failIfRequested()
- return '<qos></qos>'
+
+ if not self._metadata:
+ e = libvirt.libvirtError("No metadata")
+ e.err = [libvirt.VIR_ERR_NO_DOMAIN_METADATA]
+ raise e
+ return self._metadata
+
+ def setMetadata(self, type, xml, prefix, uri, flags):
+ self._metadata = xml
def schedulerParameters(self):
return {'vcpu_quota': vm._NO_CPU_QUOTA,
@@ -862,6 +872,279 @@
fake._dom = FakeDomain(virtError=libvirt.VIR_ERR_NO_DOMAIN)
self.assertEqual(fake._getVmPolicy(), None)
+ def _xml_sanitizer(self, text):
+ return re.sub(">[\t\n ]+<", "><", text).strip()
+
+ def testUpdateVmPolicy(self):
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ machine._dom = dom
+
+ policy = {
+ "vcpuLimit": 50,
+ "ioTune": [
+ {
+ "name": "test-device-by-name",
+ "maximum": {
+ "total_bytes_sec": 200, "total_iops_sec": 201,
+ "read_bytes_sec": 202, "read_iops_sec": 203,
+ "write_bytes_sec": 204, "write_iops_sec": 205
+ },
+ "guaranteed": {
+ "total_bytes_sec": 100, "total_iops_sec": 101,
+ "read_bytes_sec": 102, "read_iops_sec": 103,
+ "write_bytes_sec": 104, "write_iops_sec": 105
+ }
+ },
+ {
+ "path": "test-device-by-path",
+ "maximum": {
+ "total_bytes_sec": 400, "total_iops_sec": 401,
+ "read_bytes_sec": 402, "read_iops_sec": 403,
+ "write_bytes_sec": 404, "write_iops_sec": 405
+ },
+ "guaranteed": {
+ "total_bytes_sec": 300, "total_iops_sec": 301,
+ "read_bytes_sec": 302, "read_iops_sec": -1,
+ "write_bytes_sec": 304, "write_iops_sec": 305
+ }
+ }
+ ]
+ }
+
+ machine.updateVmPolicy(policy)
+
+ expected_xml = self._xml_sanitizer(u"""
+ <qos>
+ <vcpuLimit>50</vcpuLimit>
+ <ioTune>
+ <device name="test-device-by-name">
+ <maximum>
+ <total_bytes_sec>200</total_bytes_sec>
+ <total_iops_sec>201</total_iops_sec>
+ <read_bytes_sec>202</read_bytes_sec>
+ <read_iops_sec>203</read_iops_sec>
+ <write_bytes_sec>204</write_bytes_sec>
+ <write_iops_sec>205</write_iops_sec>
+ </maximum>
+ <guaranteed>
+ <total_bytes_sec>100</total_bytes_sec>
+ <total_iops_sec>101</total_iops_sec>
+ <read_bytes_sec>102</read_bytes_sec>
+ <read_iops_sec>103</read_iops_sec>
+ <write_bytes_sec>104</write_bytes_sec>
+ <write_iops_sec>105</write_iops_sec>
+ </guaranteed>
+ </device>
+ <device path="test-device-by-path">
+ <maximum>
+ <total_bytes_sec>400</total_bytes_sec>
+ <total_iops_sec>401</total_iops_sec>
+ <read_bytes_sec>402</read_bytes_sec>
+ <read_iops_sec>403</read_iops_sec>
+ <write_bytes_sec>404</write_bytes_sec>
+ <write_iops_sec>405</write_iops_sec>
+ </maximum>
+ <guaranteed>
+ <total_bytes_sec>300</total_bytes_sec>
+ <total_iops_sec>301</total_iops_sec>
+ <read_bytes_sec>302</read_bytes_sec>
+ <write_bytes_sec>304</write_bytes_sec>
+ <write_iops_sec>305</write_iops_sec>
+ </guaranteed>
+ </device>
+ </ioTune>
+ </qos>
+ """)
+
+ self.assertEqual(expected_xml, self._xml_sanitizer(dom._metadata))
+
+ def testIoTuneParser(self):
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ machine._dom = dom
+
+ ioTuneValues = {
+ "name": "test-device-by-name",
+ "path": "test-path",
+ "maximum": {
+ "total_bytes_sec": 200, "total_iops_sec": 201,
+ "read_bytes_sec": 202, "read_iops_sec": 203,
+ "write_bytes_sec": 204, "write_iops_sec": 205
+ },
+ "guaranteed": {
+ "total_bytes_sec": 100, "total_iops_sec": 101,
+ "read_bytes_sec": 102, "read_iops_sec": 103,
+ "write_bytes_sec": 104, "write_iops_sec": 105
+ }
+ }
+
+ dom = ioTuneToDom(ioTuneValues)
+ parsed = ioTuneDomToValues(dom)
+
+ self.assertEqual(ioTuneValues, parsed)
+
+ def testIoTuneMerge(self):
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ machine._dom = dom
+
+ ioTuneValues1 = {
+ "path": "test-path",
+ "maximum": {
+ "total_bytes_sec": 0, "total_iops_sec": 0,
+ "read_bytes_sec": 0,
+ "write_bytes_sec": 999, "write_iops_sec": 0
+ },
+ "guaranteed": {
+ "total_bytes_sec": 999, "total_iops_sec": 0,
+ "read_bytes_sec": 0, "read_iops_sec": 0,
+ "write_bytes_sec": 0, "write_iops_sec": 0
+ }
+ }
+
+ ioTuneValues2 = {
+ "name": "test-device-by-name",
+ "maximum": {
+ "total_bytes_sec": 200, "total_iops_sec": 201,
+ "read_bytes_sec": 202, "read_iops_sec": 203,
+ "write_iops_sec": 205
+ },
+ "guaranteed": {
+ "total_bytes_sec": -1, "total_iops_sec": 101,
+ "read_bytes_sec": 102, "read_iops_sec": 103,
+ "write_bytes_sec": 104, "write_iops_sec": 105
+ }
+ }
+
+ ioTuneExpectedValues = {
+ "name": "test-device-by-name",
+ "path": "test-path",
+ "maximum": {
+ "total_bytes_sec": 200, "total_iops_sec": 201,
+ "read_bytes_sec": 202, "read_iops_sec": 203,
+ "write_bytes_sec": 999, "write_iops_sec": 205
+ },
+ "guaranteed": {
+ "total_bytes_sec": -1, "total_iops_sec": 101,
+ "read_bytes_sec": 102, "read_iops_sec": 103,
+ "write_bytes_sec": 104, "write_iops_sec": 105
+ }
+ }
+
+ ioTuneMerged = ioTuneMerge(ioTuneValues1, ioTuneValues2)
+
+ self.assertEqual(ioTuneMerged, ioTuneExpectedValues)
+
+ def testUpdateExistingVmPolicy(self):
+ with FakeVM() as machine:
+ dom = FakeDomain()
+ dom._metadata = """
+ <qos>
+ <vcpuLimit>999</vcpuLimit>
+ <ioTune>
+ <device name='test-device-by-name'>
+ <maximum>
+ <totalBytes>9999</totalBytes>
+ </maximum>
+ </device>
+ <device name='other-device'>
+ <maximum>
+ <totalBytes>9999</totalBytes>
+ </maximum>
+ </device>
+ </ioTune>
+ </qos>
+ """
+
+ machine._dom = dom
+
+ policy = {
+ "vcpuLimit": 50,
+ "ioTune": [
+ {
+ "name": "test-device-by-name",
+ "maximum": {
+ "total_bytes_sec": 200, "total_iops_sec": 201,
+ "read_bytes_sec": 202, "read_iops_sec": 203,
+ "write_bytes_sec": 204, "write_iops_sec": 205
+ },
+ "guaranteed": {
+ "total_bytes_sec": 100, "total_iops_sec": 101,
+ "read_bytes_sec": 102, "read_iops_sec": 103,
+ "write_bytes_sec": 104, "write_iops_sec": 105
+ }
+ },
+ {
+ "path": "test-device-by-path",
+ "maximum": {
+ "total_bytes_sec": 400, "total_iops_sec": 401,
+ "read_bytes_sec": 402, "read_iops_sec": 403,
+ "write_bytes_sec": 404, "write_iops_sec": 405
+ },
+ "guaranteed": {
+ "total_bytes_sec": 300, "total_iops_sec": 301,
+ "read_bytes_sec": 302, "read_iops_sec": 303,
+ "write_bytes_sec": 304, "write_iops_sec": 305
+ }
+ }
+ ]
+ }
+
+ machine.updateVmPolicy(policy)
+
+ expected_xml = self._xml_sanitizer(u"""
+ <qos>
+ <ioTune>
+ <device name="other-device">
+ <maximum>
+ <totalBytes>9999</totalBytes>
+ </maximum>
+ </device>
+ <device name="test-device-by-name">
+ <maximum>
+ <total_bytes_sec>200</total_bytes_sec>
+ <total_iops_sec>201</total_iops_sec>
+ <read_bytes_sec>202</read_bytes_sec>
+ <read_iops_sec>203</read_iops_sec>
+ <write_bytes_sec>204</write_bytes_sec>
+ <write_iops_sec>205</write_iops_sec>
+ </maximum>
+ <guaranteed>
+ <total_bytes_sec>100</total_bytes_sec>
+ <total_iops_sec>101</total_iops_sec>
+ <read_bytes_sec>102</read_bytes_sec>
+ <read_iops_sec>103</read_iops_sec>
+ <write_bytes_sec>104</write_bytes_sec>
+ <write_iops_sec>105</write_iops_sec>
+ </guaranteed>
+ </device>
+ <device path="test-device-by-path">
+ <maximum>
+ <total_bytes_sec>400</total_bytes_sec>
+ <total_iops_sec>401</total_iops_sec>
+ <read_bytes_sec>402</read_bytes_sec>
+ <read_iops_sec>403</read_iops_sec>
+ <write_bytes_sec>404</write_bytes_sec>
+ <write_iops_sec>405</write_iops_sec>
+ </maximum>
+ <guaranteed>
+ <total_bytes_sec>300</total_bytes_sec>
+ <total_iops_sec>301</total_iops_sec>
+ <read_bytes_sec>302</read_bytes_sec>
+ <read_iops_sec>303</read_iops_sec>
+ <write_bytes_sec>304</write_bytes_sec>
+ <write_iops_sec>305</write_iops_sec>
+ </guaranteed>
+ </device>
+ </ioTune>
+ <vcpuLimit>50</vcpuLimit>
+ </qos>
+ """)
+
+ self.maxDiff = None
+ self.assertEqual(expected_xml, self._xml_sanitizer(dom._metadata))
+
class FakeGuestAgent(object):
def getGuestInfo(self):
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 8129935..9e32874 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -935,6 +935,7 @@
%{_datadir}/%{vdsm_name}/virt/utils.py*
%{_datadir}/%{vdsm_name}/virt/vmchannels.py*
%{_datadir}/%{vdsm_name}/virt/vmstatus.py*
+%{_datadir}/%{vdsm_name}/virt/vmtune.py*
%{_datadir}/%{vdsm_name}/virt/vm.py*
%{_datadir}/%{vdsm_name}/virt/vmexitreason.py*
%{_datadir}/%{vdsm_name}/virt/vmpowerdown.py*
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 7cd8753..47124af 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -2310,6 +2310,44 @@
'*ioTune': 'VmDiskDeviceIoTuneParams'}}
##
+# @VmDiskDeviceTuneParams:
+#
+# Extra parameters for VM disk devices. At least one
+# device identifier (name/path) is needed.
+#
+# @name: #optional The name of the taget device
+#
+# @path: #optional The path of the taget device
+#
+# @ioTune: IO tune parameters
+#
+# Since: 4.15.0
+##
+{'type': 'VmDiskDeviceTuneParams',
+ 'data': {'*name': 'str', '*path': 'str',
+ 'ioTune': 'VmDiskDeviceIoTuneParams'}}
+
+##
+# @VmDiskDeviceTuneLimits:
+#
+# Extra parameters for VM disk devices.
+#
+# @name: #optional The name of the target device
+#
+# @path: #optional The path of the target device
+#
+# @guaranteed: IO tune parameters - guaranteed values
+#
+# @maximum: IO tune parameters - the hard limits
+#
+# Since: 4.15.0
+##
+{'type': 'VmDiskDeviceTuneLimits',
+ 'data': {'*name': 'str', '*path': 'str',
+ 'guaranteed': 'VmDiskDeviceIoTuneParams',
+ 'maximum': 'VmDiskDeviceIoTuneParams'}}
+
+##
# @VmDiskDeviceVolumeChainEntry:
#
# Identifies one volume in a VM disk device volume chain.
@@ -7493,14 +7531,32 @@
'returns': 'TaskStatus'}
##
+# @UpdateVmPolicyParams:
+#
+# QoS policy update data
+#
+# @vcpuLimit: #optional vcpu limit to set - the value is a percentage
+# representation of the amount of cpu from the Host that
+# the VM can consume
+#
+# @ioTune: #optional list of ioTune limits to set
+#
+# Since: 4.15.0
+##
+{'type': 'UpdateVmPolicyParams',
+ 'data': {'*vcpuLimit': 'int',
+ '*ioTune': ['VmDiskDeviceTuneLimits']}}
+
+##
# @VM.updateVmPolicy:
#
# Set VM SLA parameters
#
# @vmID: The UUID of the VM
#
-# @vcpuLimit: vcpu limit to set - the value is a percentage representation
-# of the amount of cpu from the Host that the VM can consume
+# @params: The UpdateVmPolicyParams structure that defines
+# the changes that are to be applied to the current
+# QoS policy.
#
# Returns:
# The VM definition, as updated
@@ -7508,4 +7564,5 @@
# Since: 4.15.0
##
{'command': {'class': 'VM', 'name': 'updateVmPolicy'},
- 'data': {'vmID': 'UUID', 'vcpuLimit': 'int'}}
+ 'data': {'vmID': 'UUID', 'params': 'UpdateVmPolicyParams'},
+ 'returns': 'TaskStatus'}
diff --git a/vdsm/virt/Makefile.am b/vdsm/virt/Makefile.am
index c3262a1..be480d2 100644
--- a/vdsm/virt/Makefile.am
+++ b/vdsm/virt/Makefile.am
@@ -31,4 +31,6 @@
vmexitreason.py \
vmpowerdown.py \
vmstatus.py \
+ vmtune.py \
+ utils.py \
$(NULL)
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index bc58899..b3dd8f2 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -64,6 +64,7 @@
from . import sampling
from . import vmexitreason
from . import vmstatus
+from .vmtune import updateIoTuneDom
from .utils import XMLElement
from vmpowerdown import VmShutdown, VmReboot
@@ -3632,6 +3633,7 @@
Supported properties are:
vcpuLimit - the CPU usage hard limit
+ ioTune - the IO limits
In the case not all properties are provided, the missing properties'
setting will be left intact.
@@ -3677,6 +3679,20 @@
metadata_modified = True
del params['vcpuLimit']
+ if 'ioTune' in params:
+ # Make sure the top level element exists
+ ioTuneList = qos.getElementsByTagName("ioTune")
+ if not ioTuneList:
+ ioTuneElement = XMLElement("ioTune")
+ ioTuneList.append(ioTuneElement)
+ qos.appendChild(ioTuneElement)
+ metadata_modified = True
+
+ if updateIoTuneDom(ioTuneList[0], params["ioTune"]) > 0:
+ metadata_modified = True
+
+ del params['ioTune']
+
# Check remaining fields in params and report the list of unsupported
# params to the log
diff --git a/vdsm/virt/vmtune.py b/vdsm/virt/vmtune.py
new file mode 100644
index 0000000..06558fe
--- /dev/null
+++ b/vdsm/virt/vmtune.py
@@ -0,0 +1,225 @@
+#
+# Copyright 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import itertools
+from copy import deepcopy
+import logging
+
+from .utils import XMLElement
+
+log = logging.getLogger(__name__)
+
+
+def ioTuneValuesToDom(values, dom):
+ """
+ Create a DOM representation of the passed iotune values and
+ attach it to the dom object in the form of nodes.
+
+ :param values: Dictionary mapping iotune key to its value
+ :param dom: XML DOM object to attach the result to
+ """
+ ops = ("total", "read", "write")
+ units = ("bytes", "iops")
+
+ for op, unit in itertools.product(ops, units):
+ name = op + "_" + unit + "_sec"
+ if name in values and values[name] >= 0:
+ el = XMLElement(name)
+ el.appendTextNode(str(values[name]))
+ dom.appendChild(el)
+
+
+def collectInnerElements(el, d):
+ """
+ This helper method collects all nodes in el and adds them
+ to dictionary d.
+
+ :param el: XML DOM element object with text only children
+ :param d: Dictionary to add the values to
+ """
+ for chel in el.childNodes:
+ # skip text body
+ if chel.localName is None:
+ continue
+ try:
+ d[chel.localName] = int(chel.childNodes[0].data)
+ except (IndexError, ValueError):
+ log.exception("Invalid value for %s", chel.localName)
+
+
+def ioTuneDomToValues(dom):
+ """
+ This method converts the VmDiskDeviceTuneLimits structure from its
+ XML representation to the dictionary representation.
+
+ :param dom: XML DOM object to parse
+ :return: The structure in the dictionary form
+ """
+ values = {}
+
+ if dom.hasAttribute("name"):
+ values["name"] = dom.getAttribute("name")
+
+ if dom.hasAttribute("path"):
+ values["path"] = dom.getAttribute("path")
+
+ els = dom.getElementsByTagName("guaranteed")
+ if els:
+ values["guaranteed"] = {}
+ collectInnerElements(els[0], values["guaranteed"])
+
+ els = dom.getElementsByTagName("maximum")
+ if els:
+ values["maximum"] = {}
+ for chel in els[0].childNodes:
+ collectInnerElements(els[0], values["maximum"])
+
+ return values
+
+
+def ioTuneToDom(tune):
+ """
+ This method converts the VmDiskDeviceTuneLimits structure from the
+ dictionary representation to the XML representation.
+
+ :param tune: Dictionary representation of VmDiskDeviceTuneLimits
+ :return: DOM XML of device node filled with values
+ """
+ device = XMLElement("device")
+
+ if "name" in tune and tune["name"]:
+ device.setAttribute("name", tune["name"])
+
+ if "path" in tune and tune["path"]:
+ device.setAttribute("path", tune["path"])
+
+ if "maximum" in tune:
+ maximum = XMLElement("maximum")
+ device.appendChild(maximum)
+ ioTuneValuesToDom(tune["maximum"], maximum)
+
+ if "guaranteed" in tune:
+ guaranteed = XMLElement("guaranteed")
+ device.appendChild(guaranteed)
+ ioTuneValuesToDom(tune["guaranteed"], guaranteed)
+
+ return device
+
+
+def ioTuneMerge(old, new):
+ """
+ Merge two VmDiskDeviceTuneLimits structures in their dictionary form
+ and return the new iotune setting.
+
+ :param old: VmDiskDeviceTuneLimits in dict form
+ :param new: VmDiskDeviceTuneLimits in dict form
+ :return: old + new (in this order) in the dict form
+ """
+
+ result = deepcopy(old)
+
+ if "name" in new:
+ result["name"] = new["name"]
+
+ if "path" in new:
+ result["path"] = new["path"]
+
+ result.setdefault("maximum", {})
+ if "maximum" in new:
+ result["maximum"].update(new["maximum"])
+
+ result.setdefault("guaranteed", {})
+ if "guaranteed" in new:
+ result["guaranteed"].update(new["guaranteed"])
+
+ return result
+
+
+def createDeviceIndex(ioTune):
+ """
+ Create by name / by path dictionaries from the XML representation.
+ Returns a tuple (by_name, by_path) where the items are the respective
+ dictionaries.
+
+ :param dom: The root element (devices) to traverse
+ :return: (by_name, by_path)
+ """
+
+ ioTuneByPath = {}
+ ioTuneByName = {}
+
+ for el in ioTune.getElementsByTagName("device"):
+ # Only one of the path and name fields is mandatory
+ if el.hasAttribute("path"):
+ ioTuneByPath[el.getAttribute("path")] = el
+
+ if el.hasAttribute("name"):
+ ioTuneByName[el.getAttribute("name")] = el
+
+ return ioTuneByName, ioTuneByPath
+
+
+def updateIoTuneDom(ioTune, tunables):
+ """
+ This method takes a list of VmDiskDeviceTuneLimits objects and applies
+ the changes to the XML element representing the current iotune settings,
+
+ The return value then specifies how many devices were updated.
+
+ :param ioTune: XML object representing the ioTune metadata node
+ :param tunables: list of VmDiskDeviceTuneLimits objects
+ :return: number of updated devices
+ """
+
+ count = 0
+
+ # Get all existing ioTune records and create name/path index
+ ioTuneByName, ioTuneByPath = createDeviceIndex(ioTune)
+
+ for limit_object in tunables:
+ old_tune = None
+ if ("name" in limit_object
+ and limit_object["name"] in ioTuneByName):
+ old_tune = ioTuneByName[limit_object["name"]]
+ ioTune.removeChild(old_tune)
+ elif ("path" in limit_object
+ and limit_object["path"] in ioTuneByPath):
+ old_tune = ioTuneByPath[limit_object["path"]]
+ ioTune.removeChild(old_tune)
+
+ if old_tune is not None:
+ old_object = ioTuneDomToValues(old_tune)
+ limit_object = ioTuneMerge(old_object, limit_object)
+
+ new_tune = ioTuneToDom(limit_object)
+ ioTune.appendChild(new_tune)
+ count += 1
+
+ # Make sure everything is OK when the same name is passed
+ # twice by updating the index
+ if ("name" in limit_object
+ and limit_object["name"] in ioTuneByName):
+ ioTuneByName[limit_object["name"]] = new_tune
+
+ if ("path" in limit_object
+ and limit_object["path"] in ioTuneByPath):
+ ioTuneByPath[limit_object["path"]] = new_tune
+
+ return count
--
To view, visit http://gerrit.ovirt.org/30074
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4ed108fbb2bf9d9af80577b2905242bf9f8c4221
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: tests: fix pep8 errors
by Martin Sivak
Hello Dan Kenigsberg, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30073
to review the following change.
Change subject: tests: fix pep8 errors
......................................................................
tests: fix pep8 errors
Commit: a2890d5d614e856a44102d61576a8591a8d2e52f
introduced pep8 and pyflakes errors in tests.
This patch fixes that.
Change-Id: Ieefeb049d295ed89cdfedc7ccc9daee05b7de712
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/29960
Reviewed-by: Martin Sivák <msivak(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/vmTests.py
1 file changed, 3 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/73/30073/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index b52fe4d..02b1339 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -24,7 +24,6 @@
import re
import shutil
import tempfile
-import xml.dom.minidom
import xml.etree.ElementTree as ET
import libvirt
@@ -62,7 +61,7 @@
def _failIfRequested(self):
if self._virtError != libvirt.VIR_ERR_OK:
- err = libvirt.libvirtError(defmsg='')
+ err = libvirt.libvirtError(defmsg='')
err.err = [self._virtError]
raise err
@@ -850,15 +849,13 @@
def testGetVmPolicySucceded(self):
with FakeVM() as fake:
fake._dom = FakeDomain()
- self.assertTrue(isinstance(fake._getVmPolicy(),
- xml.dom.minidom.Element))
+ self.assertXML(fake._getVmPolicy(), '<qos/>')
def testGetVmPolicyEmptyOnNoMetadata(self):
with FakeVM() as fake:
fake._dom = FakeDomain(
virtError=libvirt.VIR_ERR_NO_DOMAIN_METADATA)
- self.assertTrue(isinstance(fake._getVmPolicy(),
- xml.dom.minidom.Element))
+ self.assertXML(fake._getVmPolicy(), '<qos/>')
def testGetVmPolicyFailOnNoDomain(self):
with FakeVM() as fake:
--
To view, visit http://gerrit.ovirt.org/30073
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ieefeb049d295ed89cdfedc7ccc9daee05b7de712
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
9 years, 6 months
Change in vdsm[ovirt-3.5]: vm: fix getVmPolicy return type.
by Martin Sivak
Hello Dan Kenigsberg, Francesco Romani,
I'd like you to do a code review. Please visit
http://gerrit.ovirt.org/30072
to review the following change.
Change subject: vm: fix getVmPolicy return type.
......................................................................
vm: fix getVmPolicy return type.
in case of error, getVmPolicy will return a VDSM API return
value, which may confuse the caller.
This patch makes getVmPolicy returns explicitely None on error,
and let the caller handle this condition and bail out correctly.
Change-Id: I4c1d79283ee2de4a5dcf54f3544ec346c68837e1
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/29930
Reviewed-by: Martin Sivák <msivak(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/vmTests.py
M vdsm/virt/vm.py
2 files changed, 34 insertions(+), 5 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/72/30072/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 2762e51..b52fe4d 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -24,6 +24,7 @@
import re
import shutil
import tempfile
+import xml.dom.minidom
import xml.etree.ElementTree as ET
import libvirt
@@ -54,9 +55,16 @@
class FakeDomain:
- def __init__(self, xml=''):
+ def __init__(self, xml='', virtError=libvirt.VIR_ERR_OK):
self._xml = xml
self.devXml = ''
+ self._virtError = virtError
+
+ def _failIfRequested(self):
+ if self._virtError != libvirt.VIR_ERR_OK:
+ err = libvirt.libvirtError(defmsg='')
+ err.err = [self._virtError]
+ raise err
def info(self):
raise libvirt.libvirtError(defmsg='')
@@ -71,7 +79,8 @@
return -1
def metadata(self, type, uri, flags):
- return None
+ self._failIfRequested()
+ return '<qos></qos>'
def schedulerParameters(self):
return {'vcpu_quota': vm._NO_CPU_QUOTA,
@@ -838,6 +847,24 @@
def testBuildCmdLinePPC64(self):
self.assertBuildCmdLine(CONF_TO_DOMXML_PPC64)
+ def testGetVmPolicySucceded(self):
+ with FakeVM() as fake:
+ fake._dom = FakeDomain()
+ self.assertTrue(isinstance(fake._getVmPolicy(),
+ xml.dom.minidom.Element))
+
+ def testGetVmPolicyEmptyOnNoMetadata(self):
+ with FakeVM() as fake:
+ fake._dom = FakeDomain(
+ virtError=libvirt.VIR_ERR_NO_DOMAIN_METADATA)
+ self.assertTrue(isinstance(fake._getVmPolicy(),
+ xml.dom.minidom.Element))
+
+ def testGetVmPolicyFailOnNoDomain(self):
+ with FakeVM() as fake:
+ fake._dom = FakeDomain(virtError=libvirt.VIR_ERR_NO_DOMAIN)
+ self.assertEqual(fake._getVmPolicy(), None)
+
class FakeGuestAgent(object):
def getGuestInfo(self):
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 28c4819..bc58899 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -3656,8 +3656,10 @@
#
# Get the current QoS block
- qos = self._getVmPolicy()
metadata_modified = False
+ qos = self._getVmPolicy()
+ if qos is None:
+ return self._reportError(key='updateVmPolicyErr')
#
# Process provided properties, remove property after it is processed
@@ -3719,8 +3721,8 @@
METADATA_VM_TUNE_URI, 0)
except libvirt.libvirtError as e:
if e.get_error_code() != libvirt.VIR_ERR_NO_DOMAIN_METADATA:
- return self._reportException(key='updateVmPolicyErr',
- msg=e.message)
+ self.log.exception("getVmPolicy failed")
+ return None
metadata = xml.dom.minidom.parseString(metadata_xml)
return metadata.getElementsByTagName("qos")[0]
--
To view, visit http://gerrit.ovirt.org/30072
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4c1d79283ee2de4a5dcf54f3544ec346c68837e1
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Martin Sivák <msivak(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Francesco Romani <fromani(a)redhat.com>
9 years, 6 months