
From: CrÃstian Deives <cristiandeives@gmail.com> If several users try to update the same VM at the same time, an error may happen due to concurrent access. Define a dictionary containing one lock per each VM, and use it when updating the VM: the lock is acquired before the update operation begins and it is released when the operation finishes (whether by success or failure). Signed-off-by: CrÃstian Deives <cristiandeives@gmail.com> Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/kimchi/model/vms.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 8463287..b579712 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -22,6 +22,7 @@ import lxml.etree as ET import os import random import string +import threading import time import uuid @@ -78,6 +79,9 @@ XPATH_DOMAIN_UUID = '/domain/uuid' XPATH_NUMA_CELL = './cpu/numa/cell' +# key: VM name; value: lock object +vm_locks = {} + class VMsModel(object): def __init__(self, **kargs): @@ -215,10 +219,16 @@ class VMModel(object): self.stats = {} def update(self, name, params): - dom = self.get_vm(name, self.conn) - vm_name, dom = self._static_vm_update(name, dom, params) - self._live_vm_update(dom, params) - return vm_name + lock = vm_locks.get(name) + if lock is None: + lock = threading.Lock() + vm_locks[name] = lock + + with lock: + dom = self.get_vm(name, self.conn) + vm_name, dom = self._static_vm_update(name, dom, params) + self._live_vm_update(dom, params) + return vm_name def clone(self, name): """Clone a virtual machine based on an existing one. -- 1.9.1