Skip to content

Commit 56f0448

Browse files
authored
Linstor fix migration while node offline (#8610)
* linstor: Add util method getBestErrorMessage from main * linstor: failed remove of allow-two-primaries is no fatal error * linstor: Fix failure if a Linstor node is down while migrating If a Linstor node is down while migrating resource, allow-two-primaries setting will fail because we can't reach the downed node. But it will still set the property on the other nodes and migration should work. We now just report an error instead of completely failing.
1 parent 3fa052c commit 56f0448

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -269,27 +269,35 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S
269269
}
270270

271271
final DevelopersApi api = getLinstorAPI(pool);
272+
String rscName;
272273
try
273274
{
274-
final String rscName = getLinstorRscName(volumePath);
275+
rscName = getLinstorRscName(volumePath);
275276

276277
ResourceMakeAvailable rma = new ResourceMakeAvailable();
277278
ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, localNodeName, rma);
278279
checkLinstorAnswersThrow(answers);
279280

281+
} catch (ApiException apiEx) {
282+
s_logger.error(apiEx);
283+
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
284+
}
285+
286+
try
287+
{
280288
// allow 2 primaries for live migration, should be removed by disconnect on the other end
281289
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
282290
Properties props = new Properties();
283291
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
284292
rdm.setOverrideProps(props);
285-
answers = api.resourceDefinitionModify(rscName, rdm);
293+
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
286294
if (answers.hasError()) {
287295
s_logger.error("Unable to set 'allow-two-primaries' on " + rscName);
288-
throw new CloudRuntimeException(answers.get(0).getMessage());
296+
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
289297
}
290298
} catch (ApiException apiEx) {
291299
s_logger.error(apiEx);
292-
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
300+
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
293301
}
294302
return true;
295303
}
@@ -353,19 +361,21 @@ public boolean disconnectPhysicalDiskByPath(String localPath)
353361
ApiCallRcList answers = api.resourceDefinitionModify(rsc.get().getName(), rdm);
354362
if (answers.hasError())
355363
{
356-
s_logger.error("Failed to remove 'allow-two-primaries' on " + rsc.get().getName());
357-
throw new CloudRuntimeException(answers.get(0).getMessage());
364+
s_logger.error(
365+
String.format("Failed to remove 'allow-two-primaries' on %s: %s",
366+
rsc.get().getName(), LinstorUtil.getBestErrorMessage(answers)));
367+
// do not fail here as removing allow-two-primaries property isn't fatal
358368
}
359369

360370
return true;
361371
}
362372
s_logger.warn("Linstor: Couldn't find resource for this path: " + localPath);
363373
} catch (ApiException apiEx) {
364-
s_logger.error(apiEx);
365-
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
374+
s_logger.error(apiEx.getBestMessage());
375+
// do not fail here as removing allow-two-primaries property isn't fatal
366376
}
367377
}
368-
return false;
378+
return true;
369379
}
370380

371381
@Override

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.linbit.linstor.api.ApiException;
2121
import com.linbit.linstor.api.Configuration;
2222
import com.linbit.linstor.api.DevelopersApi;
23+
import com.linbit.linstor.api.model.ApiCallRc;
24+
import com.linbit.linstor.api.model.ApiCallRcList;
2325
import com.linbit.linstor.api.model.ProviderKind;
2426
import com.linbit.linstor.api.model.ResourceGroup;
2527
import com.linbit.linstor.api.model.StoragePool;
@@ -47,6 +49,15 @@ public static DevelopersApi getLinstorAPI(String linstorUrl) {
4749
return new DevelopersApi(client);
4850
}
4951

52+
public static String getBestErrorMessage(ApiCallRcList answers) {
53+
return answers != null && !answers.isEmpty() ?
54+
answers.stream()
55+
.filter(ApiCallRc::isError)
56+
.findFirst()
57+
.map(ApiCallRc::getMessage)
58+
.orElse((answers.get(0)).getMessage()) : null;
59+
}
60+
5061
public static long getCapacityBytes(String linstorUrl, String rscGroupName) {
5162
DevelopersApi linstorApi = getLinstorAPI(linstorUrl);
5263
try {

0 commit comments

Comments
 (0)