Daniel Erez has uploaded a new change for review.

Change subject: core: ensure unique unit for VirtIO_SCSI and SPAR_VSCSI disks
......................................................................

core: ensure unique unit for VirtIO_SCSI and SPAR_VSCSI disks

Ensuring a unique address unit value for disks attached with
VirtIO_SCSI or SPAR_VSCSI interfaces. The selected units may
collide as the search process is depended on the VmDevice
addresses which are updated asynchronously by the VmsMonitoring.
E.g. when hot-plugging multiple disks using a script, identical
unit values might be selected for different disks.

Hence:
* Updating VmDevice address in DB right after selecting an
  available unit value.
* Taking an EngineLock on addAddress method to avoid races.

Change-Id: I5e621618e8891fca52b48bff437cc4c2a1f695db
Bug-Url: https://bugzilla.redhat.com/1206374
Signed-off-by: Daniel Erez <de...@redhat.com>
---
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/locks/LockingGroup.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java
2 files changed, 42 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/71/39471/1

diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/locks/LockingGroup.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/locks/LockingGroup.java
index 458424f..3aa005f 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/locks/LockingGroup.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/locks/LockingGroup.java
@@ -32,6 +32,7 @@
     SYNC_LUNS,
     /** This group is used for indication that an operation is executed using 
the specified host */
     VDS_EXECUTION,
-    VDS_POOL_AND_STORAGE_CONNECTIONS;
+    VDS_POOL_AND_STORAGE_CONNECTIONS,
+    VM_DISK_HOT_PLUG;
 
 }
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java
index 77b4c67..49c67de 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java
@@ -1,30 +1,39 @@
 package org.ovirt.engine.core.vdsbroker.vdsbroker;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.commons.lang.StringUtils;
 import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VmDevice;
 import org.ovirt.engine.core.common.businessentities.storage.Disk;
-import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType;
 import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
 import org.ovirt.engine.core.common.businessentities.storage.DiskInterface;
+import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType;
 import org.ovirt.engine.core.common.businessentities.storage.LunDisk;
 import org.ovirt.engine.core.common.businessentities.storage.PropagateErrors;
 import org.ovirt.engine.core.common.businessentities.storage.VolumeFormat;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.common.locks.LockingGroup;
+import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.common.utils.VmDeviceType;
 import org.ovirt.engine.core.common.vdscommands.HotPlugDiskVDSParameters;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.utils.archstrategy.ArchStrategyFactory;
+import org.ovirt.engine.core.utils.lock.EngineLock;
+import org.ovirt.engine.core.utils.lock.LockManagerFactory;
+import org.ovirt.engine.core.utils.transaction.TransactionMethod;
+import org.ovirt.engine.core.utils.transaction.TransactionSupport;
 import org.ovirt.engine.core.vdsbroker.architecture.GetControllerIndices;
 import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcStringUtils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 public class HotPlugDiskVDSCommand<P extends HotPlugDiskVDSParameters> extends 
VdsBrokerCommand<P> {
 
     protected Map<String, Object> sendInfo = new HashMap<String, Object>();
+    private EngineLock vmLock;
 
     public HotPlugDiskVDSCommand(P parameters) {
         super(parameters);
@@ -103,6 +112,7 @@
     }
 
     private void addAddress(Map<String, Object> map, String address) {
+        lockVmWithWait();
         if (getParameters().getDisk().getDiskInterface() != 
DiskInterface.VirtIO_SCSI &&
                 getParameters().getDisk().getDiskInterface() != 
DiskInterface.SPAPR_VSCSI) {
             if (StringUtils.isNotBlank(address)) {
@@ -127,6 +137,7 @@
                 addAddressForScsiDisk(map, address, vmDeviceUnitMap, 
sPaprVscsiIndex, true);
             }
         }
+        LockManagerFactory.getLockManager().releaseLock(vmLock);
     }
 
     private void addAddressForScsiDisk(Map<String, Object> map,
@@ -151,5 +162,30 @@
         else {
             map.put(VdsProperties.Address, 
VmInfoBuilder.createAddressForScsiDisk(controllerIndex, availableUnit));
         }
+
+        // Updating device's address immediately (instead of waiting to 
VmsMonitoring)
+        // to prevent a duplicate unit value (i.e. ensuring a unique unit 
value).
+        updateVmDeviceAddress(map.get(VdsProperties.Address).toString());
+    }
+
+    private void updateVmDeviceAddress(final String address) {
+        TransactionSupport.executeInNewTransaction(new 
TransactionMethod<Void>() {
+            @Override
+            public Void runInTransaction() {
+                VmDevice vmDevice = getParameters().getVmDevice();
+                vmDevice.setAddress(address);
+                DbFacade.getInstance().getVmDeviceDao().update(vmDevice);
+                return null;
+            }
+        });
+    }
+
+    protected void lockVmWithWait() {
+        Map<String, Pair<String, String>> exsluciveLock =
+                Collections.singletonMap(getParameters().getVmId().toString(),
+                        new Pair<>(LockingGroup.VM_DISK_HOT_PLUG.toString(),
+                                
VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED.toString()));
+        vmLock = new EngineLock(exsluciveLock, null);
+        LockManagerFactory.getLockManager().acquireLockWait(vmLock);
     }
 }


-- 
To view, visit https://gerrit.ovirt.org/39471
To unsubscribe, visit https://gerrit.ovirt.org/settings

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

Reply via email to