Skip to content

Commit 1096574

Browse files
committed
linstor: Only set allow-two-primaries if resource is already in use
For live migrate we need the allow-two-primaries option, but we don't know exactly if we are called for a migration operation. Now also check if at least any of the resources is in use somewhere and only then set the option.
1 parent e6f80dd commit 1096574

2 files changed

Lines changed: 37 additions & 10 deletions

File tree

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
@@ -234,6 +234,28 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, Qemu
234234
}
235235
}
236236

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

260282
try
261283
{
262-
// allow 2 primaries for live migration, should be removed by disconnect on the other end
263-
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
264-
Properties props = new Properties();
265-
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
266-
rdm.setOverrideProps(props);
267-
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
268-
if (answers.hasError()) {
269-
s_logger.error("Unable to set 'allow-two-primaries' on " + rscName);
270-
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
271-
}
284+
allow2PrimariesIfInUse(api, rscName);
272285
} catch (ApiException apiEx) {
273286
s_logger.error(apiEx);
274287
// 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: 14 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,17 @@ 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+
return rscs.stream().anyMatch(rsc -> rsc.getState() != null ? rsc.getState().isInUse() : false);
199+
}
186200
}

0 commit comments

Comments
 (0)