CS-16499: releaseNic - lock the nic row in the DB before checking its state. Hold the lock till the nics attributes + nicCount is updated

Conflicts:

	server/src/com/cloud/network/NetworkManagerImpl.java

Conflicts:

	server/src/com/cloud/network/NetworkManagerImpl.java
This commit is contained in:
Alena Prokharchyk 2012-10-18 18:45:00 -07:00
parent 49919bcc6f
commit 7bd7884f57

View File

@ -2094,7 +2094,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
List<NicVO> 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<NicVO>() {
@Override
@ -2193,6 +2194,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
@DB
public void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean forced) throws
ConcurrentOperationException, ResourceUnavailableException {
List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
@ -2200,6 +2202,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
releaseNic(vmProfile, nic);
}
}
@Override
public void releaseNic(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, Nic nic)
throws ConcurrentOperationException, ResourceUnavailableException {
@ -2208,11 +2212,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
protected void releaseNic(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, NicVO nic)
protected void releaseNic(VirtualMachineProfile<? extends VMInstanceVO> 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();
}
}