Skip to content

Commit 0fa71f5

Browse files
committed
Merge remote-tracking branch 'origin/4.18' into 4.19
2 parents 582249c + 0577b0a commit 0fa71f5

4 files changed

Lines changed: 72 additions & 22 deletions

File tree

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,7 @@ public String toString() {
222222
guestDef.append("<boot dev='" + bo + "'/>\n");
223223
}
224224
}
225-
if (_arch == null || !_arch.equals("aarch64")) {
226-
guestDef.append("<smbios mode='sysinfo'/>\n");
227-
}
225+
guestDef.append("<smbios mode='sysinfo'/>\n");
228226
guestDef.append("</os>\n");
229227
if (iothreads) {
230228
guestDef.append(String.format("<iothreads>%s</iothreads>", NUMBER_OF_IOTHREADS));

plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,28 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, Qemu
235235
}
236236
}
237237

238+
/**
239+
* Checks if the given resource is in use by drbd on any host and
240+
* if so set the drbd option allow-two-primaries
241+
* @param api linstor api object
242+
* @param rscName resource name to set allow-two-primaries if in use
243+
* @throws ApiException if any problem connecting to the Linstor controller
244+
*/
245+
private void allow2PrimariesIfInUse(DevelopersApi api, String rscName) throws ApiException {
246+
if (LinstorUtil.isResourceInUse(api, rscName)) {
247+
// allow 2 primaries for live migration, should be removed by disconnect on the other end
248+
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
249+
Properties props = new Properties();
250+
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
251+
rdm.setOverrideProps(props);
252+
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
253+
if (answers.hasError()) {
254+
s_logger.error("Unable to set 'allow-two-primaries' on " + rscName);
255+
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
256+
}
257+
}
258+
}
259+
238260
@Override
239261
public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details)
240262
{
@@ -261,16 +283,7 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S
261283

262284
try
263285
{
264-
// allow 2 primaries for live migration, should be removed by disconnect on the other end
265-
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
266-
Properties props = new Properties();
267-
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
268-
rdm.setOverrideProps(props);
269-
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
270-
if (answers.hasError()) {
271-
s_logger.error("Unable to set 'allow-two-primaries' on " + rscName);
272-
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
273-
}
286+
allow2PrimariesIfInUse(api, rscName);
274287
} catch (ApiException apiEx) {
275288
s_logger.error(apiEx);
276289
// do not fail here as adding allow-two-primaries property is only a problem while live migrating

plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.linbit.linstor.api.model.ApiCallRcList;
2525
import com.linbit.linstor.api.model.Node;
2626
import com.linbit.linstor.api.model.ProviderKind;
27+
import com.linbit.linstor.api.model.Resource;
2728
import com.linbit.linstor.api.model.ResourceGroup;
2829
import com.linbit.linstor.api.model.ResourceWithVolumes;
2930
import com.linbit.linstor.api.model.StoragePool;
@@ -183,4 +184,22 @@ public static long getCapacityBytes(String linstorUrl, String rscGroupName) {
183184
throw new CloudRuntimeException(apiEx);
184185
}
185186
}
187+
188+
/**
189+
* Check if any resource of the given name is InUse on any host.
190+
*
191+
* @param api developer api object to use
192+
* @param rscName resource name to check in use state.
193+
* @return True if a resource found that is in use(primary) state, else false.
194+
* @throws ApiException forwards api errors
195+
*/
196+
public static boolean isResourceInUse(DevelopersApi api, String rscName) throws ApiException {
197+
List<Resource> rscs = api.resourceList(rscName, null, null);
198+
if (rscs != null) {
199+
return rscs.stream()
200+
.anyMatch(rsc -> rsc.getState() != null && Boolean.TRUE.equals(rsc.getState().isInUse()));
201+
}
202+
s_logger.error("isResourceInUse: null returned from resourceList");
203+
return false;
204+
}
186205
}

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
353353
if (possibleAddr.getState() != State.Free) {
354354
continue;
355355
}
356+
if (s_logger.isDebugEnabled()) {
357+
s_logger.debug(String.format("trying ip address %s", possibleAddr.getAddress()));
358+
}
356359
possibleAddr.setSourceNat(sourceNat);
357360
possibleAddr.setAllocatedTime(new Date());
358361
possibleAddr.setAllocatedInDomainId(owner.getDomainId());
@@ -367,15 +370,9 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
367370
possibleAddr.setAssociatedWithNetworkId(guestNetworkId);
368371
possibleAddr.setVpcId(vpcId);
369372
}
370-
if (_ipAddressDao.lockRow(possibleAddr.getId(), true) != null) {
371-
final IPAddressVO userIp = _ipAddressDao.findById(possibleAddr.getId());
372-
if (userIp.getState() == State.Free) {
373-
possibleAddr.setState(State.Allocating);
374-
if (_ipAddressDao.update(possibleAddr.getId(), possibleAddr)) {
375-
finalAddress = possibleAddr;
376-
break;
377-
}
378-
}
373+
finalAddress = assignIpAddressWithLock(possibleAddr);
374+
if (finalAddress != null) {
375+
break;
379376
}
380377
}
381378

@@ -397,6 +394,29 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
397394
});
398395
}
399396

397+
private IPAddressVO assignIpAddressWithLock(IPAddressVO possibleAddr) {
398+
IPAddressVO finalAddress = null;
399+
IPAddressVO userIp = _ipAddressDao.acquireInLockTable(possibleAddr.getId());
400+
if (userIp != null) {
401+
if (s_logger.isDebugEnabled()) {
402+
s_logger.debug(String.format("locked row for ip address %s (id: %s)", possibleAddr.getAddress(), possibleAddr.getUuid()));
403+
}
404+
if (userIp.getState() == State.Free) {
405+
possibleAddr.setState(State.Allocating);
406+
if (_ipAddressDao.update(possibleAddr.getId(), possibleAddr)) {
407+
s_logger.info(String.format("successfully allocated ip address %s", possibleAddr.getAddress()));
408+
finalAddress = possibleAddr;
409+
}
410+
} else {
411+
if (s_logger.isDebugEnabled()) {
412+
s_logger.debug(String.format("locked ip address %s is not free (%s)", possibleAddr.getAddress(), userIp.getState()));
413+
}
414+
}
415+
_ipAddressDao.releaseFromLockTable(possibleAddr.getId());
416+
}
417+
return finalAddress;
418+
}
419+
400420
@Override
401421
public boolean configure(String name, Map<String, Object> params) {
402422
// populate providers

0 commit comments

Comments
 (0)