diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7506985ab99..4f72a808e36 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2094,7 +2094,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vmProfile.getId()); // we have to implement default nics first - to ensure that default network elements start up first in multiple - // nics case)(need for setting DNS on Dhcp to domR's Ip4 address) + //nics case + // (need for setting DNS on Dhcp to domR's Ip4 address) Collections.sort(nics, new Comparator() { @Override @@ -2193,6 +2194,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override + @DB public void release(VirtualMachineProfile vmProfile, boolean forced) throws ConcurrentOperationException, ResourceUnavailableException { List nics = _nicDao.listByVmId(vmProfile.getId()); @@ -2200,6 +2202,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag releaseNic(vmProfile, nic); } } + + @Override public void releaseNic(VirtualMachineProfile vmProfile, Nic nic) throws ConcurrentOperationException, ResourceUnavailableException { @@ -2208,11 +2212,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } - protected void releaseNic(VirtualMachineProfile vmProfile, NicVO nic) + protected void releaseNic(VirtualMachineProfile vmProfile, NicVO nicVO) throws ConcurrentOperationException, ResourceUnavailableException { - NetworkVO network = _networksDao.findById(nic.getNetworkId()); - if (nic.getState() == Nic.State.Reserved || nic.getState() == Nic.State.Reserving) { - Nic.State originalState = nic.getState(); + //lock the nic + Transaction txn = Transaction.currentTxn(); + txn.start(); + + NicVO nic = _nicDao.lockRow(nicVO.getId(), true); + if (nic == null) { + throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic); + } + + Nic.State originalState = nic.getState(); + NetworkVO network = _networksDao.findById(nicVO.getNetworkId()); + + if (originalState == Nic.State.Reserved || originalState == Nic.State.Reserving) { if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { NetworkGuru guru = _networkGurus.get(network.getGuruName()); nic.setState(Nic.State.Releasing); @@ -2228,6 +2242,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _nicDao.update(nic.getId(), nic); } } + //commit the transaction before proceeding releasing nic profile on the network elements + txn.commit(); + // Perform release on network elements for (NetworkElement element : _networkElements) { if (s_logger.isDebugEnabled()) { @@ -2241,7 +2258,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { nic.setState(Nic.State.Allocated); updateNic(nic, network.getId(), -1); + txn.commit(); } + } else { + //commiting the empty transaction here as we have to release the lock we've held + txn.commit(); } }