Change in vdsm[master]: Don't prepare image with illegal volumes
by alitke@redhat.com
Adam Litke has uploaded a new change for review.
Change subject: Don't prepare image with illegal volumes
......................................................................
Don't prepare image with illegal volumes
The irs verb 'prepareImage' is used only by clientIF when preparing the
host to start a VM. Currently, this operation succeeds even if one or
more of the volumes in the image is illegal. Since we should never
permit a VM to start with an illegal disk, check for this and report an
error if any illegal volumes are found.
The pivot stage of a live merge operation depends on this behavior to
ensure that a VM is not accidentally started using a stale leaf volume.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1206722
Change-Id: Ie543aeb8bdb52305419613ab6297681817124308
Signed-off-by: Adam Litke <alitke(a)redhat.com>
---
M vdsm/storage/hsm.py
1 file changed, 5 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/02/39302/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 8f07586..dc8ca77 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -3225,6 +3225,11 @@
if leafUUID not in imgVolumes:
raise se.VolumeDoesNotExist(leafUUID)
+ for volUUID in imgVolumes:
+ legality = dom.produceVolume(imgUUID, volUUID).getLegality()
+ if legality == volume.ILLEGAL_VOL:
+ raise se.prepareIllegalVolumeError(volUUID)
+
imgPath = dom.activateVolumes(imgUUID, imgVolumes)
if spUUID and spUUID != sd.BLANK_UUID:
runImgPath = dom.linkBCImage(imgPath, imgUUID)
--
To view, visit https://gerrit.ovirt.org/39302
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie543aeb8bdb52305419613ab6297681817124308
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke(a)redhat.com>
8 years, 6 months
Change in vdsm[master]: tests: increase timeout to 30 seconds
by ykaplan@redhat.com
Yeela Kaplan has uploaded a new change for review.
Change subject: tests: increase timeout to 30 seconds
......................................................................
tests: increase timeout to 30 seconds
Increase maximum timeout to 30 seconds instead of only 1.
On automation testing gc is a bit slower,
so we want to be safe and avoid unit tests failing.
Change-Id: I62cca38db73a0344d927e58cf79ca14e323278bf
Signed-off-by: Yeela Kaplan <ykaplan(a)redhat.com>
---
M tests/outOfProcessTests.py
1 file changed, 14 insertions(+), 10 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/67/36267/1
diff --git a/tests/outOfProcessTests.py b/tests/outOfProcessTests.py
index 8cb89a7..18c97e9 100644
--- a/tests/outOfProcessTests.py
+++ b/tests/outOfProcessTests.py
@@ -63,6 +63,7 @@
def testAmountOfInstancesPerPoolName(self):
idle = oop.IOPROC_IDLE_TIME
+ maxSleep = 30
try:
oop.IOPROC_IDLE_TIME = 5
poolA = "A"
@@ -74,16 +75,19 @@
oop.getProcessPool(poolB)
self.assertEquals(wrapper(), None)
gc.collect()
- time.sleep(1)
- gc.collect()
- try:
- self.assertEquals(ioproc(), None)
- except AssertionError:
- logging.info("GARBAGE: %s", gc.garbage)
- refs = gc.get_referrers(ioproc())
- logging.info(refs)
- logging.info(gc.get_referrers(*refs))
- raise
+ for i in xrange(1, maxSleep+1):
+ time.sleep(1)
+ gc.collect()
+ try:
+ self.assertEquals(ioproc(), None)
+ break
+ except AssertionError:
+ if (i == maxSleep):
+ logging.info("GARBAGE: %s", gc.garbage)
+ refs = gc.get_referrers(ioproc())
+ logging.info(refs)
+ logging.info(gc.get_referrers(*refs))
+ raise
finally:
oop.IOPROC_IDLE_TIME = idle
--
To view, visit http://gerrit.ovirt.org/36267
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I62cca38db73a0344d927e58cf79ca14e323278bf
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yeela Kaplan <ykaplan(a)redhat.com>
8 years, 6 months
Change in vdsm[master]: configfile: remove unneeded methods.
by mtayer@redhat.com
mooli tayer has uploaded a new change for review.
Change subject: configfile: remove unneeded methods.
......................................................................
configfile: remove unneeded methods.
Change-Id: Icf08bfebc83a9af5eb3c7de48f9a51d2263766fd
Signed-off-by: Mooli Tayer <mtayer(a)redhat.com>
---
M lib/vdsm/tool/configurators/configfile.py
M tests/toolTests.py
2 files changed, 2 insertions(+), 106 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/36324/1
diff --git a/lib/vdsm/tool/configurators/configfile.py b/lib/vdsm/tool/configurators/configfile.py
index d8b7fdd..d1e0472 100644
--- a/lib/vdsm/tool/configurators/configfile.py
+++ b/lib/vdsm/tool/configurators/configfile.py
@@ -83,7 +83,6 @@
version,
sectionStart='## beginning of configuration section by vdsm',
sectionEnd='## end of configuration section by vdsm',
- prefix='# VDSM backup',
lineComment='by vdsm'):
if not os.path.exists(filename):
raise OSError(
@@ -94,7 +93,6 @@
self._context = False
self._sectionStart = sectionStart
self._sectionEnd = sectionEnd
- self._prefix = prefix
# remove 'lineComment' at 4.0. see 'Backward compatibility'
self._lineComment = lineComment
self._version = version
@@ -104,9 +102,6 @@
raise RuntimeError("can only enter once")
self._entries = {}
self._context = True
- self._prefixRemove = None
- self._prefixAdd = None
- self._section = None
self._oldmod = os.stat(self._filename).st_mode
self._remove = None
self._rmstate = BEFORE
@@ -131,11 +126,6 @@
continue
if not self._remove or self._rmstate != WITHIN:
- if self._prefixRemove:
- if line.startswith(self._prefix):
- line = line[len(self._prefix):]
- if self._prefixAdd:
- line = self._prefix + line
m = confpat.match(line.rstrip())
if m:
oldentries.add(m.group('key'))
@@ -149,11 +139,6 @@
def _end(self):
return "%s-%s\n" % (self._sectionEnd, self._version)
-
- def _writeSection(self, f):
- f.write(self._start())
- f.write(self._section)
- f.write(self._end())
def _writeEntries(self, f, oldentries):
f.write(self._start())
@@ -170,8 +155,6 @@
try:
oldlines, oldentries = self._getOldContent()
with os.fdopen(fd, 'w', ) as f:
- if self._section:
- self._writeSection(f)
f.writelines(oldlines)
if self._entries:
self._writeEntries(f, oldentries)
@@ -199,32 +182,6 @@
all pairs are added in a comment wrapped section.
"""
self._entries[key] = val
-
- @context
- def prependSection(self, section):
- """
- add 'section' in the beginning of the file.
- section is added in a comment wrapped section.
-
- Only one section is currently supported.
- """
- self._section = section
-
- @context
- def prefixLines(self):
- """
- Add self.prefix to the beginning of each line.
- No editing is done on new content added by this config file.
- """
- self._prefixAdd = True
-
- @context
- def unprefixLines(self):
- """
- Remove self.prefix from each line starting with it.
- No editing is done on new content added by this config file.
- """
- self._prefixRemove = True
@context
def removeConf(self):
diff --git a/tests/toolTests.py b/tests/toolTests.py
index 82a2668..89a93bf 100644
--- a/tests/toolTests.py
+++ b/tests/toolTests.py
@@ -452,66 +452,6 @@
"key4=val\n"
"# end conf-3.4.4\n")
- def testPrefixAndPrepend(self):
- self._writeConf("/var/log/libvirt/libvirtd.log {\n"
- " weekly\n"
- "}\n")
- with ConfigFile(self.tname,
- version='3.4.4',
- sectionStart="# start conf",
- sectionEnd="# end conf",
- prefix="# comment ") as conf:
- conf.prefixLines()
- conf.prependSection("Some text to\n"
- "add at the top\n")
- with open(self.tname, 'r') as f:
- self.assertEqual(f.read(),
- "# start conf-3.4.4\n"
- "Some text to\n"
- "add at the top\n"
- "# end conf-3.4.4\n"
- "# comment /var/log/libvirt/libvirtd.log {\n"
- "# comment weekly\n"
- "# comment }\n")
-
- def testPrefixIdempotencey(self):
- original = (
- "/var/log/libvirt/libvirtd.log {\n"
- " weekly\n"
- "}\n"
- )
- self._writeConf(original)
- with ConfigFile(self.tname,
- version='3.4.4',
- sectionStart="# start conf",
- sectionEnd="# end conf",
- prefix="# comment ") as conf:
- conf.prefixLines()
- with open(self.tname, 'r') as f:
- self.assertEqual(f.read(),
- "# comment /var/log/libvirt/libvirtd.log {\n"
- "# comment weekly\n"
- "# comment }\n")
- with ConfigFile(self.tname,
- version='3.4.4',
- sectionStart="# start conf",
- sectionEnd="# end conf",
- prefix="# comment ") as conff:
- conff.unprefixLines()
- with open(self.tname, 'r') as f:
- self.assertEqual(f.read(), original)
-
- def testRemoveEntireLinePrefix(self):
- self._writeConf("# comment\n")
- with ConfigFile(self.tname,
- version='3.4.4',
- sectionStart="# start conf",
- sectionEnd="# end conf",
- prefix="# comment") as conf:
- conf.unprefixLines()
- with open(self.tname, 'r') as f:
- self.assertEqual(f.read(), "\n")
-
def testRemoveConfSection(self):
self._writeConf("key=val\n"
"remove me!(see 'Backward compatibility')# by vdsm\n"
@@ -523,8 +463,7 @@
with ConfigFile(self.tname,
version='3.4.4',
sectionStart="# start conf",
- sectionEnd="# end conf",
- prefix="# comment") as conf:
+ sectionEnd="# end conf") as conf:
conf.removeConf()
with open(self.tname, 'r') as f:
self.assertEqual(f.read(), "key=val\n"
@@ -536,7 +475,7 @@
version='3.4.4',
sectionStart="# start conf",
sectionEnd="# end conf")
- self.assertRaises(RuntimeError, conff.prefixLines)
+ self.assertRaises(RuntimeError, conff.addEntry, 'key', 'val')
self.assertRaises(RuntimeError, conff.removeConf)
def testHasConf(self):
--
To view, visit http://gerrit.ovirt.org/36324
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icf08bfebc83a9af5eb3c7de48f9a51d2263766fd
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: mooli tayer <mtayer(a)redhat.com>
8 years, 6 months
Change in vdsm[ovirt-3.5]: tests: Enable again utils.memoized in the tests
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/40030
to review the following change.
Change subject: tests: Enable again utils.memoized in the tests
......................................................................
tests: Enable again utils.memoized in the tests
Tests that may leave dirt in memoized functions should invalidate the
functions during teardown.
Since we disabled memoizing becuase of pulluted memoized functions in
caps module, caps tests invalidate all memoized functions now.
Change-Id: I019e2a2ad75973511cccd195a7e9eaa105d8154f
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37841
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
Tested-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/capsTests.py
M tests/testrunner.py
2 files changed, 7 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/30/40030/1
diff --git a/tests/capsTests.py b/tests/capsTests.py
index e3f7d6a..d0ac3d5 100644
--- a/tests/capsTests.py
+++ b/tests/capsTests.py
@@ -41,6 +41,13 @@
class TestCaps(TestCaseBase):
+
+ def tearDown(self):
+ for name in dir(caps):
+ obj = getattr(caps, name)
+ if isinstance(obj, utils.memoized):
+ obj.invalidate()
+
def _readCaps(self, fileName):
testPath = os.path.realpath(__file__)
dirName = os.path.split(testPath)[0]
diff --git a/tests/testrunner.py b/tests/testrunner.py
index 13fe55e..37b4c95 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -411,10 +411,6 @@
raise AssertionError(msg)
-def fakeMemoized(func):
- return func
-
-
if __name__ == '__main__':
if "--help" in sys.argv:
print("testrunner options:\n"
@@ -426,6 +422,4 @@
# Mock panic() calls for tests
utils.panic = panicMock
- # Memoization during tests is a bad idea.
- utils.memoized = fakeMemoized
run()
--
To view, visit https://gerrit.ovirt.org/40030
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I019e2a2ad75973511cccd195a7e9eaa105d8154f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 6 months
Change in vdsm[ovirt-3.5]: utils: Add memoized invalidation
by fromani@redhat.com
Hello Piotr Kliczewski, Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/40029
to review the following change.
Change subject: utils: Add memoized invalidation
......................................................................
utils: Add memoized invalidation
We learned in the hard way that memoizing and monkey-patching do work
nicely together. However, disabling memoizing during the tests means
that we do not test the same code in the application.
This patch adds invalidate() method to memoized functions, so tests can
clean up properly after they modify memozied data.
This can also be used by application code to invalidate memoized
functions in certain conditions.
Change-Id: I3053b8ecc567f7c3154f7473dfd6b587823313ae
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37788
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 lib/vdsm/utils.py
M tests/utilsTests.py
2 files changed, 67 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/29/40029/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 4619b74..944cf4d 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -971,9 +971,14 @@
self.cache[args] = value
return value
+ def invalidate(self):
+ self.cache.clear()
+
def __get__(self, obj, objtype):
"""Support instance methods."""
- return functools.partial(self.__call__, obj)
+ wrapper = functools.partial(self.__call__, obj)
+ wrapper.invalidate = self.cache.clear
+ return wrapper
def validateMinimalKeySet(dictionary, reqParams):
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 5b3614d..2a0b8ef 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -18,6 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
+import collections
import os.path
import contextlib
import errno
@@ -662,3 +663,63 @@
self.assertTrue(
hack < base/2,
"picklecopy [%f] not faster than deepcopy [%f]" % (hack, base))
+
+
+@expandPermutations
+class MemoizedTests(TestCaseBase):
+
+ def setUp(self):
+ self.values = {}
+ self.accessed = collections.defaultdict(int)
+
+ @permutations([[()], [("a",)], [("a", "b")]])
+ def test_memoized_method(self, args):
+ self.values[args] = 42
+ self.assertEqual(self.accessed[args], 0)
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 1)
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 1)
+
+ @permutations([[()], [("a",)], [("a", "b")]])
+ def test_memoized_function(self, args):
+ self.values[args] = 42
+ self.assertEqual(self.accessed[args], 0)
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 1)
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 1)
+
+ def test_key_error(self):
+ self.assertRaises(KeyError, self.memoized_method)
+ self.assertRaises(KeyError, self.memoized_method, "a")
+ self.assertRaises(KeyError, self.memoized_method, "a", "b")
+
+ def test_invalidate_method(self):
+ args = ("a",)
+ self.values[args] = 42
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.memoized_method.invalidate()
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 2)
+
+ def test_invalidate_function(self):
+ args = ("a",)
+ self.values[args] = 42
+ self.assertEqual(memoized_function(self, *args), 42)
+ memoized_function.invalidate()
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 2)
+
+ @utils.memoized
+ def memoized_method(self, *args):
+ return self.get(args)
+
+ def get(self, key):
+ self.accessed[key] += 1
+ return self.values[key]
+
+
+(a)utils.memoized
+def memoized_function(test, *args):
+ return test.get(args)
--
To view, visit https://gerrit.ovirt.org/40029
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3053b8ecc567f7c3154f7473dfd6b587823313ae
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
8 years, 6 months
Change in vdsm[ovirt-3.5]: tests: disable memoization in testrunner
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/39949
to review the following change.
Change subject: tests: disable memoization in testrunner
......................................................................
tests: disable memoization in testrunner
memoization during tests is harmful, because
it adds another one hidden layer of global state
shared across test runs.
This may lead -and actually did- to hard
to debug failures in apparently unrelated code.
The net result is waste of developer's time,
and decreased trust in automated tests
because of mysterious failures.
To fix that, we now monkeypatch in testrunner
only utils.memoized with a fake which avoids caching.
Change-Id: Ibd986403a76268995b83c9e6ac400e942ed24cb6
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37748
Reviewed-by: Nir Soffer <nsoffer(a)redhat.com>
Tested-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/testrunner.py
1 file changed, 6 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/49/39949/1
diff --git a/tests/testrunner.py b/tests/testrunner.py
index 37b4c95..13fe55e 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -411,6 +411,10 @@
raise AssertionError(msg)
+def fakeMemoized(func):
+ return func
+
+
if __name__ == '__main__':
if "--help" in sys.argv:
print("testrunner options:\n"
@@ -422,4 +426,6 @@
# Mock panic() calls for tests
utils.panic = panicMock
+ # Memoization during tests is a bad idea.
+ utils.memoized = fakeMemoized
run()
--
To view, visit https://gerrit.ovirt.org/39949
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibd986403a76268995b83c9e6ac400e942ed24cb6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 6 months
Change in vdsm[ovirt-3.5]: tests: clear libvirtconnection cache
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/39948
to review the following change.
Change subject: tests: clear libvirtconnection cache
......................................................................
tests: clear libvirtconnection cache
the libvirtconnection has a cache to reuse connections,
and this caching doesn't play well with the monkeypatching
which we do in tests.
In libvirtconnectionTests, we create fake libvirt objects,
most notably fake virConnect-s. Unfortunately, the test fails
to clean up properly the libvirtconnection cache.
So, the test runs just fine in isolation, but if run in batch
like in 'make check', later tests which expect the real object
become broken.
The failure presents itself like the following:
AttributeError: 'virConnect' object has no attribute 'getMemoryStats'
This patch fixes this error adding a facility to clear
the libvirtconnection cache, and clearing it after each
test.
Change-Id: If4d64920e5f26c276accf26b7a532461d04f02df
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37747
Reviewed-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M lib/vdsm/libvirtconnection.py
M tests/libvirtconnectionTests.py
2 files changed, 12 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/48/39948/1
diff --git a/lib/vdsm/libvirtconnection.py b/lib/vdsm/libvirtconnection.py
index b1332db..33fdf11 100644
--- a/lib/vdsm/libvirtconnection.py
+++ b/lib/vdsm/libvirtconnection.py
@@ -95,6 +95,14 @@
return utils.retry(libvirtOpen, timeout=10, sleep=0.2)
+def _clear():
+ """
+ For clearing connections during the tests.
+ """
+ with __connectionLock:
+ __connections.clear()
+
+
def get(target=None, killOnFailure=True):
"""Return current connection to libvirt or open a new one.
Use target to get/create the connection object linked to that object.
diff --git a/tests/libvirtconnectionTests.py b/tests/libvirtconnectionTests.py
index 1ac60a0..18e1984 100644
--- a/tests/libvirtconnectionTests.py
+++ b/tests/libvirtconnectionTests.py
@@ -103,6 +103,10 @@
class testLibvirtconnection(TestCaseBase):
+
+ def tearDown(self):
+ libvirtconnection._clear()
+
@MonkeyPatch(libvirtconnection, 'libvirt', LibvirtMock())
def testCallSucceeded(self):
"""Positive test - libvirtMock does not raise any errors"""
--
To view, visit https://gerrit.ovirt.org/39948
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If4d64920e5f26c276accf26b7a532461d04f02df
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 6 months
Change in vdsm[ovirt-3.5]: vdsm: Fix memory leak in netlink.py
by jtt77777@yahoo.com
John Taylor has uploaded a new change for review.
Change subject: vdsm: Fix memory leak in netlink.py
......................................................................
vdsm: Fix memory leak in netlink.py
The documentation for libnl says that calls to rtnl_link_get_by_name
increment the reference counter and should be released by a call to
rtnl_link_put(). That's not done in the get_link(name) function where
it is used and causes a memory leak.
Add a C function prototype for the libnl rtnl_link_put function,
construct the link_info, and call rtnl_link_put before returning from
get_link(name).
Change-Id: I6e4dc72bd77e46ba4f95dd8a622f5c3288115315
Signed-off-by: John Taylor <jtt77777(a)yahoo.com>
---
M lib/vdsm/netlink.py
1 file changed, 5 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/72/39372/1
diff --git a/lib/vdsm/netlink.py b/lib/vdsm/netlink.py
index afae5ce..d822944 100644
--- a/lib/vdsm/netlink.py
+++ b/lib/vdsm/netlink.py
@@ -64,8 +64,9 @@
if not link:
raise IOError(errno.ENODEV, '%s is not present in the system' %
name)
- return _link_info(cache, link)
-
+ link_info = _link_info(cache, link)
+ _rtnl_link_put(link)
+ return link_info
class NLSocketPool(object):
"""Pool of netlink sockets."""
@@ -332,5 +333,7 @@
_nl_af2str = _int_char_proto(('nl_af2str', LIBNL))
_rtnl_scope2str = _int_char_proto(('rtnl_scope2str', LIBNL_ROUTE))
+_rtnl_link_put = _none_proto(('rtnl_link_put', LIBNL_ROUTE))
+
_nl_link_cache = partial(_cache_manager, _rtnl_link_alloc_cache)
_nl_addr_cache = partial(_cache_manager, _rtnl_addr_alloc_cache)
--
To view, visit https://gerrit.ovirt.org/39372
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e4dc72bd77e46ba4f95dd8a622f5c3288115315
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: John Taylor <jtt77777(a)yahoo.com>
8 years, 6 months
Change in vdsm[master]: [WIP]vdsm: add support for S3/S4 suspend calls
by mpoledni@redhat.com
Martin Polednik has uploaded a new change for review.
Change subject: [WIP]vdsm: add support for S3/S4 suspend calls
......................................................................
[WIP]vdsm: add support for S3/S4 suspend calls
Change-Id: Ic30016c5cd555f5771dde8db3f1340e1c11b3da7
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/guestIF.py
M vdsm_api/vdsmapi-schema.json
4 files changed, 58 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/89/19389/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 37bb908..96119ed 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -296,6 +296,20 @@
else:
return errCode['nonresp']
+ def desktopSuspend(self, mode):
+ """
+ Sleep the guest operating system
+ """
+ try:
+ v = self._cif.vmContainer[self._UUID]
+ except KeyError:
+ return errCode['noVM']
+ v.guestAgent.desktopSuspend(mode)
+ if v.guestAgent.isResponsive():
+ return {'status': doneCode}
+ else:
+ return errCode['nonresp']
+
def desktopSendHcCommand(self, message):
"""
Send a command to the guest agent (depricated).
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index fb65ad4..046bb0c 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -352,6 +352,10 @@
vm = API.VM(vmId)
return vm.desktopLogoff(force)
+ def vmDesktopSuspend(self, vmId, mode):
+ vm = API.VM(vmId)
+ return vm.desktopSuspend(mode)
+
def vmDesktopLock(self, vmId):
vm = API.VM(vmId)
return vm.desktopLock()
@@ -836,6 +840,7 @@
(self.vmMigrationCreate, 'migrationCreate'),
(self.vmDesktopLogin, 'desktopLogin'),
(self.vmDesktopLogoff, 'desktopLogoff'),
+ (self.vmDesktopSuspend, 'desktopSuspend'),
(self.vmDesktopLock, 'desktopLock'),
(self.vmDesktopSendHcCommand, 'sendHcCmdToDesktop'),
(self.vmHibernate, 'hibernate'),
diff --git a/vdsm/guestIF.py b/vdsm/guestIF.py
index 6f09ef1..2bb654b 100644
--- a/vdsm/guestIF.py
+++ b/vdsm/guestIF.py
@@ -299,6 +299,15 @@
except:
self.log.error("desktopLogoff failed", exc_info=True)
+ def desktopSuspend(self, mode):
+ try:
+ self.log.debug('desktopSleep called')
+ cmds = ('guest-suspend-ram', 'guest-suspend-hybrid',
+ 'guest-suspend-disk')
+ self._forward(cmds['mode'], {'success_response': 'yes'})
+ except:
+ self.log.debug('desktopSleep failed', exc_info=True)
+
def desktopShutdown(self, timeout, msg):
try:
self.log.debug("desktopShutdown called")
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 27c12c1..bc54041 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -5079,6 +5079,36 @@
'data': {'vmID': 'UUID', 'force': 'bool'}}
##
+# @guestSuspendMode
+#
+# Enumeration of supported suspend modes
+#
+# @ram: S3 sleep
+#
+# @disk: S4 sleep
+#
+# @hybrid: Combination of @ram and @disk
+#
+# Since: 4.12.0
+##
+{'enum': 'guestSuspendMode', 'data': ['ram', 'disk', 'hybrid']}
+
+
+##
+# @VM.desktopSuspend:
+#
+# Suspend the guest operating system
+#
+# @vmID: The UUID of the VM
+#
+# @mode: Type of suspension
+#
+# Since: 4.12.0
+##
+{'command': {'class': 'VM', 'name': 'desktopSuspend'},
+ 'data': {'vmID': 'UUID', 'mode': 'guestSuspendMode'}}
+
+##
# @VM.desktopSendHcCommand:
#
# Send an arbitrary command to the guest agent.
--
To view, visit http://gerrit.ovirt.org/19389
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic30016c5cd555f5771dde8db3f1340e1c11b3da7
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpoledni(a)redhat.com>
8 years, 6 months
Change in vdsm[master]: vdsm: add support for hot(un)plug of pci-passthrough devices
by mpoledni@redhat.com
Martin Polednik has uploaded a new change for review.
Change subject: vdsm: add support for hot(un)plug of pci-passthrough devices
......................................................................
vdsm: add support for hot(un)plug of pci-passthrough devices
Hot(un)plug ability for pci-passthrough devices is extremely important
in order to allow for hotunplugging/migrating/hotplugging workflow as VM
cannot be migrated with pci device attached.
This patch implements the ability adding new API verbs: hotplugHostdev
and hotunplugHostdev, which attempts to append/remove the device from
domain XML and reports back the state.
Change-Id: I8fbf4a1d62789d9404e5977eb7eb01b17a1a43fb
Signed-off-by: Martin Polednik <mpoledni(a)redhat.com>
---
M client/vdsClient.py
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/vm.py
M vdsm_api/vdsmapi-schema.json
5 files changed, 166 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/23/22523/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index d549500..f00180e 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -245,6 +245,14 @@
params = {'vmId': args[0], 'drive': drive}
return self.ExecAndExit(self.s.hotunplugDisk(params))
+ def hotplugHostdev(self, args):
+ params = {'vmId': args[0], 'hostdevName': args[1]}
+ return self.ExecAndExit(self.s.hotplugNic(params))
+
+ def hotunplugHostdev(self, args):
+ params = {'vmId': args[0], 'hostdevName': args[2]}
+ return self.ExecAndExit(self.s.hotunplugNic(params))
+
def do_changeCD(self, args):
vmId = args[0]
file = self._parseDriveSpec(args[1])
diff --git a/vdsm/API.py b/vdsm/API.py
index 44d5817..51eb506 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -456,6 +456,40 @@
return curVm.hotunplugDisk(params)
+ def hotplugHostdev(self, params):
+ try:
+ utils.validateMinimalKeySet(params, ('vmId', 'hostdevName'))
+ except ValueError:
+ self.log.error('Missing one of required parameters: vmId, '
+ 'hostdevName')
+ return {'status': {'code': errCode['MissParam']['status']['code'],
+ 'message': 'Missing one of required '
+ 'parameters: vmId, hostdevName'}}
+ try:
+ curVm = self._cif.vmContainer[self._UUID]
+ except KeyError:
+ self.log.warning("vm %s doesn't exist", self._UUID)
+ return errCode['noVM']
+
+ return curVm.hotplugHostdev(params)
+
+ def hotunplugHostdev(self, params):
+ try:
+ utils.validateMinimalKeySet(params, ('vmId', 'hostdevName'))
+ except ValueError:
+ self.log.error('Missing one of required parameters: vmId, '
+ 'hostdevName')
+ return {'status': {'code': errCode['MissParam']['status']['code'],
+ 'message': 'Missing one of required '
+ 'parameters: vmId, hostdevName'}}
+ try:
+ curVm = self._cif.vmContainer[self._UUID]
+ except KeyError:
+ self.log.warning("vm %s doesn't exist", self._UUID)
+ return errCode['noVM']
+
+ return curVm.hotunplugHostdev(params)
+
def migrate(self, params):
"""
Migrate a VM to a remote host.
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 5bcd84c..847ceaf 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -279,6 +279,14 @@
vm = API.VM(params['vmId'])
return vm.hotunplugNic(params)
+ def vmHotplugHostdev(self, params):
+ vm = API.VM(params['vmId'])
+ return vm.hotplugHostdev(params)
+
+ def vmHotunplugHostdev(self, params):
+ vm = API.VM(params['vmId'])
+ return vm.hotunplugHostdev(params)
+
def vmUpdateDevice(self, vmId, params):
vm = API.VM(vmId)
return vm.vmUpdateDevice(params)
@@ -861,6 +869,8 @@
(self.vmHotunplugDisk, 'hotunplugDisk'),
(self.vmHotplugNic, 'hotplugNic'),
(self.vmHotunplugNic, 'hotunplugNic'),
+ (self.vmHotplugHostdev, 'hotplugHostdev'),
+ (self.vmHotunplugHostdev, 'hotunplugHostdev'),
(self.vmUpdateDevice, 'vmUpdateDevice'))
def getIrsMethods(self):
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 90a6c0d..224bf7b 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -3183,6 +3183,84 @@
return {'status': doneCode, 'vmList': self.status()}
+ def hotplugHostdev(self, params):
+ hostdevName = params['hostdevName']
+ hostdev = HostDevice(self.conf, self.log, **hostdevName)
+ hostdevXML = hostdev.getXML().toprettyxml(encoding='utf-8')
+ hostdev._deviceXML = hostdevXML
+ self.log.debug("Hotplug hostdev xml: %s", hostdevXML)
+
+ try:
+ self._dom.attachDevice(hostdevXML)
+ except libvirt.libvirtError as e:
+ self.log.error("Hotplug failed", exc_info=True)
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return errCode['noVM']
+ return {'status': {'code': errCode['hotplugNic']['status']['code'],
+ 'message': e.message}}
+ else:
+ # FIXME! We may have a problem here if vdsm dies right after
+ # we sent command to libvirt and before save conf. In this case
+ # we will gather almost all needed info about this NIC from
+ # the libvirt during recovery process.
+ self._devices[HOSTDEV_DEVICES].append(hostdev)
+ with self._confLock:
+ self.conf['devices'].append(hostdev)
+ self.saveState()
+
+ return {'status': doneCode, 'vmList': self.status()}
+
+ def hotunplugHostdev(self, params):
+ hostdevName = params['hostdevName']
+
+ # Find hostdev object in vm's hostdev list
+ hostdev = None
+ for dev in self._devices[HOSTDEV_DEVICES][:]:
+ if dev.name == hostdevName:
+ hostdev = dev
+ break
+
+ if hostdev:
+ hostdevXML = hostdev.getXML().toprettyxml(encoding='utf-8')
+ self.log.debug("Hotunplug hostdev xml: %s", hostdevXML)
+ self._devices[HOSTDEV_DEVICES].remove(hostdev)
+ else:
+ self.log.error("Hotunplug hostdev failed - hostdev not found: %s",
+ hostdevName)
+ return {'status': {'code': errCode['hotunplugNic']
+ ['status']['code'],
+ 'message': "NIC not found"}}
+
+ hostdevDev = None
+ for dev in self.conf['devices'][:]:
+ if (dev['type'] == HOSTDEV_DEVICES and
+ dev['name'] == hostdevName):
+ hostdevDev = dev
+ with self._confLock:
+ self.conf['devices'].remove(dev)
+ break
+
+ self.saveState()
+
+ try:
+ self._dom.detachDevice(hostdevXML)
+ except libvirt.libvirtError as e:
+ self.log.error("Hotunplug failed", exc_info=True)
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return errCode['noVM']
+ # Restore hostdev device in vm's conf and _devices
+ if hostdevDev:
+ with self._confLock:
+ self.conf['devices'].append(hostdevDev)
+ if hostdev:
+ self._devices[HOSTDEV_DEVICES].append(hostdev)
+ self.saveState()
+ return {
+ 'status': {'code': errCode['hotunplugNic']['status']['code'],
+ 'message': e.message}}
+
+ return {'status': doneCode, 'vmList': self.status()}
+
def _lookupDeviceByAlias(self, devType, alias):
for dev in self._devices[devType][:]:
if dev.alias == alias:
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 1d4e499..85f2b28 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -5793,6 +5793,42 @@
'returns': 'VmDefinition'}
##
+# @VM.hotplugHostdev:
+#
+# Add a new host device to a running VM.
+#
+# @vmID: The UUID of the VM
+#
+# @hostdevName: The name of host's device
+#
+# Returns:
+# The VM definition, as updated
+#
+# Since: 4.14.0
+##
+{'command': {'class': 'VM', 'name': 'hotplugHostdev'},
+ 'data': {'vmID': 'UUID', 'hostdevName': 'str'},
+ 'returns': 'VmDefinition'}
+
+##
+# @VM.hotunplugHostdev:
+#
+# Remove a host device from a running VM.
+#
+# @vmID: The UUID of the VM
+#
+# @hostdevName: The name of host's device
+#
+# Returns:
+# The VM definition, as updated
+#
+# Since: 4.14.0
+##
+{'command': {'class': 'VM', 'name': 'hotunplugHostdev'},
+ 'data': {'vmID': 'UUID', 'hostdevName': 'str'},
+ 'returns': 'VmDefinition'}
+
+##
# @MigrateMode:
#
# An enumeration of VM migration modes.
--
To view, visit http://gerrit.ovirt.org/22523
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8fbf4a1d62789d9404e5977eb7eb01b17a1a43fb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Polednik <mpoledni(a)redhat.com>
8 years, 6 months