Skip to content

Commit 93d4816

Browse files
committed
Merge remote-tracking branch 'origin/4.19'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> Conflicts: plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
2 parents bf9fdad + 0fa71f5 commit 93d4816

5 files changed

Lines changed: 81 additions & 27 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
@@ -223,9 +223,7 @@ public String toString() {
223223
guestDef.append("<boot dev='" + bo + "'/>\n");
224224
}
225225
}
226-
if (_arch == null || !_arch.equals("aarch64")) {
227-
guestDef.append("<smbios mode='sysinfo'/>\n");
228-
}
226+
guestDef.append("<smbios mode='sysinfo'/>\n");
229227
guestDef.append("</os>\n");
230228
if (iothreads) {
231229
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
@@ -240,6 +240,28 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, Qemu
240240
}
241241
}
242242

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

267289
try
268290
{
269-
// allow 2 primaries for live migration, should be removed by disconnect on the other end
270-
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
271-
Properties props = new Properties();
272-
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
273-
rdm.setOverrideProps(props);
274-
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
275-
if (answers.hasError()) {
276-
logger.error("Unable to set 'allow-two-primaries' on " + rscName);
277-
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
278-
}
291+
allow2PrimariesIfInUse(api, rscName);
279292
} catch (ApiException apiEx) {
280293
logger.error(apiEx);
281294
// 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;
@@ -184,4 +185,22 @@ public static long getCapacityBytes(String linstorUrl, String rscGroupName) {
184185
throw new CloudRuntimeException(apiEx);
185186
}
186187
}
188+
189+
/**
190+
* Check if any resource of the given name is InUse on any host.
191+
*
192+
* @param api developer api object to use
193+
* @param rscName resource name to check in use state.
194+
* @return True if a resource found that is in use(primary) state, else false.
195+
* @throws ApiException forwards api errors
196+
*/
197+
public static boolean isResourceInUse(DevelopersApi api, String rscName) throws ApiException {
198+
List<Resource> rscs = api.resourceList(rscName, null, null);
199+
if (rscs != null) {
200+
return rscs.stream()
201+
.anyMatch(rsc -> rsc.getState() != null && Boolean.TRUE.equals(rsc.getState().isInUse()));
202+
}
203+
s_logger.error("isResourceInUse: null returned from resourceList");
204+
return false;
205+
}
187206
}

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
351351
if (possibleAddr.getState() != State.Free) {
352352
continue;
353353
}
354+
if (s_logger.isDebugEnabled()) {
355+
s_logger.debug(String.format("trying ip address %s", possibleAddr.getAddress()));
356+
}
354357
possibleAddr.setSourceNat(sourceNat);
355358
possibleAddr.setAllocatedTime(new Date());
356359
possibleAddr.setAllocatedInDomainId(owner.getDomainId());
@@ -365,15 +368,9 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
365368
possibleAddr.setAssociatedWithNetworkId(guestNetworkId);
366369
possibleAddr.setVpcId(vpcId);
367370
}
368-
if (_ipAddressDao.lockRow(possibleAddr.getId(), true) != null) {
369-
final IPAddressVO userIp = _ipAddressDao.findById(possibleAddr.getId());
370-
if (userIp.getState() == State.Free) {
371-
possibleAddr.setState(State.Allocating);
372-
if (_ipAddressDao.update(possibleAddr.getId(), possibleAddr)) {
373-
finalAddress = possibleAddr;
374-
break;
375-
}
376-
}
371+
finalAddress = assignIpAddressWithLock(possibleAddr);
372+
if (finalAddress != null) {
373+
break;
377374
}
378375
}
379376

@@ -395,6 +392,29 @@ private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final V
395392
});
396393
}
397394

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

ui/src/components/view/DetailSettings.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<a-button
2727
type="dashed"
2828
style="width: 100%"
29-
:disabled="!('updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner())"
29+
:disabled="!(isAdminOrOwner() && hasSettingUpdatePermission())"
3030
@click="onShowAddDetail">
3131
<template #icon><plus-outlined /></template>
3232
{{ $t('label.add.setting') }}
@@ -96,8 +96,7 @@
9696
</a-list-item-meta>
9797
<template #actions>
9898
<div
99-
v-if="!disableSettings && 'updateTemplate' in $store.getters.apis &&
100-
'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner() && allowEditOfDetail(item.name)">
99+
v-if="!disableSettings && isAdminOrOwner() && allowEditOfDetail(item.name) && hasSettingUpdatePermission()">
101100
<tooltip-button
102101
:tooltip="$t('label.edit')"
103102
icon="edit-outlined"
@@ -106,8 +105,7 @@
106105
@onClick="showEditDetail(index)" />
107106
</div>
108107
<div
109-
v-if="!disableSettings && 'updateTemplate' in $store.getters.apis &&
110-
'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner() && allowEditOfDetail(item.name)">
108+
v-if="!disableSettings && isAdminOrOwner() && allowEditOfDetail(item.name) && hasSettingUpdatePermission()">
111109
<a-popconfirm
112110
:title="`${$t('label.delete.setting')}?`"
113111
@confirm="deleteDetail(index)"
@@ -342,6 +340,12 @@ export default {
342340
this.newValue = ''
343341
this.error = false
344342
this.showAddDetail = false
343+
},
344+
hasSettingUpdatePermission () {
345+
return (
346+
(this.resourceType === 'Template' && 'updateTemplate' in this.$store.getters.apis) ||
347+
(this.resourceType === 'UserVm' && 'updateVirtualMachine' in this.$store.getters.apis)
348+
)
345349
}
346350
}
347351
}

0 commit comments

Comments
 (0)