While trying to create multiple templates I got the following error on
console:
[08/Jun/2015:12:57:23] HTTP Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/cherrypy/_cprequest.py", line 670, in
respond
response.body = self.handler()
File "/usr/lib/python2.7/dist-packages/cherrypy/lib/encoding.py", line 217, in
__call__
self.body = self.oldhandler(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/cherrypy/_cpdispatch.py", line 61, in
__call__
return self.callable(*self.args, **self.kwargs)
File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 330, in index
return self.create(parse_request(), *args)
File "/home/alinefm/kimchi/src/kimchi/control/base.py", line 262, in create
name = create(*args)
File "/home/alinefm/kimchi/src/kimchi/model/templates.py", line 48, in create
user = UserTests().probe_user()
File "/home/alinefm/kimchi/src/kimchi/kvmusertests.py", line 55, in
probe_user
flags=libvirt.VIR_DOMAIN_START_AUTODESTROY)
File "/usr/lib/python2.7/dist-packages/libvirt.py", line 3424, in createXML
if ret is None:raise libvirtError('virDomainCreateXML() failed', conn=self)
libvirtError: operation failed: domain 'KVMUSERTEST_VM' already exists
with uuid 2be4b2e8-f57a-4f87-8c24-5ac59d4bb4af
The error happens because of a race condition while trying to get the kvm user
(to validate the ISO file permissions). To avoid this problem, a lock
was added to ensure the code is run once at a time.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/kvmusertests.py | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/src/kimchi/kvmusertests.py b/src/kimchi/kvmusertests.py
index 37a80d7..5724267 100644
--- a/src/kimchi/kvmusertests.py
+++ b/src/kimchi/kvmusertests.py
@@ -18,6 +18,7 @@
import platform
import psutil
+import threading
import libvirt
@@ -36,12 +37,14 @@ class UserTests(object):
<boot dev='hd'/>
</os>
</domain>"""
+ lock = threading.Lock()
user = None
@classmethod
def probe_user(cls):
- if cls.user:
- return cls.user
+ with cls.lock:
+ if cls.user:
+ return cls.user
arch = 'ppc64' if platform.machine() == 'ppc64le' \
else platform.machine()
@@ -49,23 +52,24 @@ class UserTests(object):
xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch':
arch}
with RollbackContext() as rollback:
- conn = libvirt.open(None)
- rollback.prependDefer(conn.close)
- dom = conn.createXML(xml,
- flags=libvirt.VIR_DOMAIN_START_AUTODESTROY)
- rollback.prependDefer(dom.destroy)
- filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
- with open(filename) as f:
- pidStr = f.read()
- p = psutil.Process(int(pidStr))
+ with cls.lock:
+ conn = libvirt.open(None)
+ rollback.prependDefer(conn.close)
+ f = libvirt.VIR_DOMAIN_START_AUTODESTROY
+ dom = conn.createXML(xml, flags=f)
+ rollback.prependDefer(dom.destroy)
+ filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
+ with open(filename) as f:
+ pidStr = f.read()
+ p = psutil.Process(int(pidStr))
- # bug fix #357
- # in psutil 2.0 and above versions, username will be a method,
- # not a string
- if callable(p.username):
- cls.user = p.username()
- else:
- cls.user = p.username
+ # bug fix #357
+ # in psutil 2.0 and above versions, username will be a method,
+ # not a string
+ if callable(p.username):
+ cls.user = p.username()
+ else:
+ cls.user = p.username
return cls.user
--
2.1.0