Skip to content

Commit c916f30

Browse files
committed
CLOUDSTACK-7828.Avoid marking IPs already in Allocated as Allocated again. Use row lock to ensure that prev state is either Allocating or Free. This will inturn avoid logging duplicate events
1 parent c401dbc commit c916f30

1 file changed

Lines changed: 21 additions & 23 deletions

File tree

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

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -807,32 +807,32 @@ public IPAddressVO doInTransaction(TransactionStatus status) throws Insufficient
807807
@Override
808808
public void markPublicIpAsAllocated(final IPAddressVO addr) {
809809

810-
assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : "Unable to transition from state " + addr.getState() + " to "
811-
+ IpAddress.State.Allocated;
812810
Transaction.execute(new TransactionCallbackNoReturn() {
813811
@Override
814812
public void doInTransactionWithoutResult(TransactionStatus status) {
815-
Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
816-
817-
addr.setState(IpAddress.State.Allocated);
818-
_ipAddressDao.update(addr.getId(), addr);
819-
820-
// Save usage event
821-
if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
822-
VlanVO vlan = _vlanDao.findById(addr.getVlanId());
823-
824-
String guestType = vlan.getVlanType().toString();
825-
826-
if (!isIpDedicated(addr)) {
827-
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(),
828-
addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid());
829-
}
830-
831-
if (updateIpResourceCount(addr)) {
832-
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
813+
Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
814+
synchronized (this) {
815+
if (_ipAddressDao.lockRow(addr.getId(),true) != null) {
816+
IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
817+
if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) {
818+
addr.setState(IpAddress.State.Allocated);
819+
_ipAddressDao.update(addr.getId(), addr);
820+
// Save usage event
821+
if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
822+
VlanVO vlan = _vlanDao.findById(addr.getVlanId());
823+
String guestType = vlan.getVlanType().toString();
824+
if (!isIpDedicated(addr)) {
825+
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(),
826+
addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid());
827+
}
828+
if (updateIpResourceCount(addr)) {
829+
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
830+
}
831+
}
832+
}
833+
}
833834
}
834835
}
835-
}
836836
});
837837
}
838838

@@ -922,7 +922,6 @@ public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAdd
922922
public boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException {
923923
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
924924
boolean success = true;
925-
926925
// CloudStack will take a lazy approach to associate an acquired public IP to a network service provider as
927926
// it will not know what service an acquired IP will be used for. An IP is actually associated with a provider when first
928927
// rule is applied. Similarly when last rule on the acquired IP is revoked, IP is not associated with any provider
@@ -941,7 +940,6 @@ public boolean applyIpAssociations(Network network, boolean continueOnError) thr
941940
}
942941
}
943942
}
944-
945943
return success;
946944
}
947945

0 commit comments

Comments
 (0)