Liron Aravot has uploaded a new change for review.

Change subject: core: WIP : RemoveImageDisk - race when updating snapshots ovf 
(#828192)
......................................................................

core: WIP : RemoveImageDisk - race when updating snapshots ovf (#828192)

https://bugzilla.redhat.com/show_bug.cgi?id=828192

when removing an image disk, it should be removed from all the snapshots
it's contained within. the removal from the image snapshots includes an
update to the snapshot ovf (saved at ovirt DB). the update is an
read-update-write operation, so when two or more disks are removed from
the same snapshot a race condition might occur.
this patch adds a lock on the snapshot when performing the operations on
the snapshot ovf to prevent the race condition.

Change-Id: Iccb44f1aa9d204477955343167133849a4146753
Signed-off-by: Liron Aravot <lara...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveImageCommand.java
1 file changed, 29 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/82/7482/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveImageCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveImageCommand.java
index bc1cb4a..642912a 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveImageCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RemoveImageCommand.java
@@ -2,9 +2,11 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.RemoveImageParameters;
@@ -22,6 +24,7 @@
 import org.ovirt.engine.core.common.businessentities.async_tasks;
 import 
org.ovirt.engine.core.common.businessentities.image_storage_domain_map_id;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
+import org.ovirt.engine.core.common.locks.LockingGroup;
 import 
org.ovirt.engine.core.common.vdscommands.DeleteImageGroupVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
 import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
@@ -29,6 +32,7 @@
 import org.ovirt.engine.core.compat.NGuid;
 import org.ovirt.engine.core.compat.TransactionScopeOption;
 import org.ovirt.engine.core.dao.VmDeviceDAO;
+import org.ovirt.engine.core.utils.lock.EngineLock;
 import org.ovirt.engine.core.utils.ovf.OvfManager;
 import org.ovirt.engine.core.utils.ovf.OvfReaderException;
 import org.ovirt.engine.core.utils.transaction.TransactionMethod;
@@ -168,18 +172,42 @@
         for (DiskImage snapshotDisk : snapshotDisks) {
             NGuid vmSnapshotId = snapshotDisk.getvm_snapshot_id();
             if (vmSnapshotId != null && 
!Guid.Empty.equals(vmSnapshotId.getValue())) {
-                Snapshot updated =
+                lockSnapshotWithWait(vmSnapshotId.getValue());
+                final Snapshot updated =
                         
prepareSnapshotConfigWithoutImageSingleImage(vmSnapshotId.getValue(),
                                 snapshotDisk.getImageId());
                 if (updated != null) {
                     result.add(updated);
+                    
TransactionSupport.executeInScope(TransactionScopeOption.Required,
+                            new TransactionMethod<Object>() {
+                                @Override
+                                public Object runInTransaction() {
+                                    getSnapshotDao().update(updated);
+                                    return null;
+                                }
+                            });
                 }
+                freeSnapshotLock();
             }
         }
 
         return result;
     }
 
+    private EngineLock snapshotEngineLock = new EngineLock();
+    private Map<String, String> snapshotsExlusiveLockMap = new HashMap<String, 
String>();
+
+    private void lockSnapshotWithWait(Guid snapshotId) {
+        snapshotsExlusiveLockMap.clear();
+        snapshotsExlusiveLockMap.put(snapshotId.toString(), 
LockingGroup.SNAPSHOT.name());
+        snapshotEngineLock.setExclusiveLocks(snapshotsExlusiveLockMap);
+        getLockManager().acquireLockWait(snapshotEngineLock);
+    }
+
+    private void freeSnapshotLock(){
+        getLockManager().releaseLock(snapshotEngineLock);
+    }
+
     /**
      * Prepare a single {@link Snapshot} object representing a snapshot of a 
given VM without the give disk.
      */


--
To view, visit http://gerrit.ovirt.org/7482
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iccb44f1aa9d204477955343167133849a4146753
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Liron Aravot <lara...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to