Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/src/main/java/com/cloud/vm/NicProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class NicProfile implements InternalIdentity, Serializable {
String iPv4Dns1;
String iPv4Dns2;
String requestedIPv4;
boolean ipv4AllocationRaceCheck;

// IPv6
String iPv6Address;
Expand Down Expand Up @@ -405,6 +406,13 @@ public void setMtu(Integer mtu) {
this.mtu = mtu;
}

public boolean getIpv4AllocationRaceCheck() {
return this.ipv4AllocationRaceCheck;
}

public void setIpv4AllocationRaceCheck(boolean ipv4AllocationRaceCheck) {
this.ipv4AllocationRaceCheck = ipv4AllocationRaceCheck;
}

//
// OTHER METHODS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1012,42 +1012,84 @@ public void saveExtraDhcpOptions(final String networkUuid, final Long nicId, fin
}
}

@DB
@Override
public Pair<NicProfile, Integer> allocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
private NicVO persistNicAfterRaceCheck(final NicVO nic, final Long networkId, final NicProfile profile, int deviceId) {
return Transaction.execute(new TransactionCallback<NicVO>() {
@Override
public NicVO doInTransaction(TransactionStatus status) {
NicVO vo = _nicDao.findByIp4AddressAndNetworkId(profile.getIPv4Address(), networkId);
if (vo == null) {
applyProfileToNic(nic, profile, deviceId);
vo = _nicDao.persist(nic);
return vo;
} else {
return null;
}
}
});
}

private NicVO checkForRaceAndAllocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
final NetworkVO ntwkVO = _networksDao.findById(network.getId());
s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network + " with requested profile " + requested);
final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, ntwkVO.getGuruName());

if (requested != null && requested.getMode() == null) {
requested.setMode(network.getMode());
}
final NicProfile profile = guru.allocate(network, requested, vm);
if (profile == null) {
return null;
}
NicVO vo = null;
boolean retryIpAllocation;
do {
retryIpAllocation = false;
final NicProfile profile = guru.allocate(network, requested, vm);
if (profile == null) {
return null;
}

if (isDefaultNic != null) {
profile.setDefaultNic(isDefaultNic);
}
if (isDefaultNic != null) {
profile.setDefaultNic(isDefaultNic);
}

if (requested != null && requested.getMode() == null) {
profile.setMode(requested.getMode());
} else {
profile.setMode(network.getMode());
}
if (requested != null && requested.getMode() == null) {
profile.setMode(requested.getMode());
} else {
profile.setMode(network.getMode());
}

vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType());

DataCenterVO dcVo = _dcDao.findById(network.getDataCenterId());
if (dcVo.getNetworkType() == NetworkType.Basic) {
configureNicProfileBasedOnRequestedIp(requested, profile, network);
}

if (profile.getIpv4AllocationRaceCheck()) {
vo = persistNicAfterRaceCheck(vo, network.getId(), profile, deviceId);
} else {
applyProfileToNic(vo, profile, deviceId);
vo = _nicDao.persist(vo);
}

if (vo == null) {
if (requested.getRequestedIPv4() != null) {
throw new InsufficientVirtualNetworkCapacityException("Unable to acquire requested Guest IP address " + requested.getRequestedIPv4() + " for network " + network, DataCenter.class, dcVo.getId());
} else {
requested.setIPv4Address(null);
}
retryIpAllocation = true;
}
} while (retryIpAllocation);

NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType());
return vo;
}

DataCenterVO dcVo = _dcDao.findById(network.getDataCenterId());
if (dcVo.getNetworkType() == NetworkType.Basic) {
configureNicProfileBasedOnRequestedIp(requested, profile, network);
@DB
@Override
public Pair<NicProfile, Integer> allocateNic(final NicProfile requested, final Network network, final Boolean isDefaultNic, int deviceId, final VirtualMachineProfile vm)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {

if (requested != null && requested.getMode() == null) {
requested.setMode(network.getMode());
}

deviceId = applyProfileToNic(vo, profile, deviceId);
vo = _nicDao.persist(vo);
NicVO vo = checkForRaceAndAllocateNic(requested, network, isDefaultNic, deviceId, vm);

final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
final NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ public NicProfile allocate(final Network network, NicProfile nic, final VirtualM
} else {
guestIp = _ipAddrMgr.acquireGuestIpAddress(network, nic.getRequestedIPv4());
}
nic.setIpv4AllocationRaceCheck(true);
}
if (guestIp == null && network.getGuestType() != GuestType.L2 && !_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class,
Expand Down