|
19 | 19 | import java.io.BufferedReader; |
20 | 20 | import java.io.IOException; |
21 | 21 | import java.io.InputStreamReader; |
| 22 | + |
| 23 | +import java.util.ArrayList; |
22 | 24 | import java.util.Collections; |
23 | 25 | import java.util.HashMap; |
24 | 26 | import java.util.List; |
|
37 | 39 |
|
38 | 40 | import com.cloud.storage.Storage; |
39 | 41 | import com.cloud.utils.exception.CloudRuntimeException; |
| 42 | + |
40 | 43 | import com.linbit.linstor.api.ApiClient; |
41 | 44 | import com.linbit.linstor.api.ApiConsts; |
42 | 45 | import com.linbit.linstor.api.ApiException; |
|
47 | 50 | import com.linbit.linstor.api.model.Properties; |
48 | 51 | import com.linbit.linstor.api.model.ProviderKind; |
49 | 52 | import com.linbit.linstor.api.model.Resource; |
| 53 | +import com.linbit.linstor.api.model.ResourceConnectionModify; |
50 | 54 | import com.linbit.linstor.api.model.ResourceDefinition; |
51 | | -import com.linbit.linstor.api.model.ResourceDefinitionModify; |
52 | 55 | import com.linbit.linstor.api.model.ResourceGroup; |
53 | 56 | import com.linbit.linstor.api.model.ResourceGroupSpawn; |
54 | 57 | import com.linbit.linstor.api.model.ResourceMakeAvailable; |
@@ -262,15 +265,19 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, Qemu |
262 | 265 | * @throws ApiException if any problem connecting to the Linstor controller |
263 | 266 | */ |
264 | 267 | private void allow2PrimariesIfInUse(DevelopersApi api, String rscName) throws ApiException { |
265 | | - if (LinstorUtil.isResourceInUse(api, rscName)) { |
| 268 | + String inUseNode = LinstorUtil.isResourceInUse(api, rscName); |
| 269 | + if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) { |
266 | 270 | // allow 2 primaries for live migration, should be removed by disconnect on the other end |
267 | | - ResourceDefinitionModify rdm = new ResourceDefinitionModify(); |
| 271 | + ResourceConnectionModify rcm = new ResourceConnectionModify(); |
268 | 272 | Properties props = new Properties(); |
269 | 273 | props.put("DrbdOptions/Net/allow-two-primaries", "yes"); |
270 | | - rdm.setOverrideProps(props); |
271 | | - ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm); |
| 274 | + props.put("DrbdOptions/Net/protocol", "C"); |
| 275 | + rcm.setOverrideProps(props); |
| 276 | + ApiCallRcList answers = api.resourceConnectionModify(rscName, inUseNode, localNodeName, rcm); |
272 | 277 | if (answers.hasError()) { |
273 | | - s_logger.error("Unable to set 'allow-two-primaries' on " + rscName); |
| 278 | + s_logger.error(String.format( |
| 279 | + "Unable to set protocol C and 'allow-two-primaries' on %s/%s/%s", |
| 280 | + inUseNode, localNodeName, rscName)); |
274 | 281 | // do not fail here as adding allow-two-primaries property is only a problem while live migrating |
275 | 282 | } |
276 | 283 | } |
@@ -310,6 +317,23 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S |
310 | 317 | return true; |
311 | 318 | } |
312 | 319 |
|
| 320 | + private void removeTwoPrimariesRcProps(DevelopersApi api, String inUseNode, String rscName) throws ApiException { |
| 321 | + ResourceConnectionModify rcm = new ResourceConnectionModify(); |
| 322 | + List<String> deleteProps = new ArrayList<>(); |
| 323 | + deleteProps.add("DrbdOptions/Net/allow-two-primaries"); |
| 324 | + deleteProps.add("DrbdOptions/Net/protocol"); |
| 325 | + rcm.deleteProps(deleteProps); |
| 326 | + ApiCallRcList answers = api.resourceConnectionModify(rscName, localNodeName, inUseNode, rcm); |
| 327 | + if (answers.hasError()) { |
| 328 | + s_logger.error( |
| 329 | + String.format("Failed to remove 'protocol' and 'allow-two-primaries' on %s/%s/%s: %s", |
| 330 | + localNodeName, |
| 331 | + inUseNode, |
| 332 | + rscName, LinstorUtil.getBestErrorMessage(answers))); |
| 333 | + // do not fail here as removing allow-two-primaries property isn't fatal |
| 334 | + } |
| 335 | + } |
| 336 | + |
313 | 337 | private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool) |
314 | 338 | { |
315 | 339 | if (volumePath == null) { |
@@ -339,27 +363,25 @@ private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool) |
339 | 363 |
|
340 | 364 |
|
341 | 365 | if (optRsc.isPresent()) { |
| 366 | + Resource rsc = optRsc.get(); |
342 | 367 | try { |
343 | | - Resource rsc = optRsc.get(); |
| 368 | + String inUseNode = LinstorUtil.isResourceInUse(api, rsc.getName()); |
| 369 | + if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) { |
| 370 | + removeTwoPrimariesRcProps(api, inUseNode, rsc.getName()); |
| 371 | + } |
| 372 | + } catch (ApiException apiEx) { |
| 373 | + s_logger.error(apiEx.getBestMessage()); |
| 374 | + // do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal |
| 375 | + } |
344 | 376 |
|
| 377 | + try { |
345 | 378 | // if diskless resource remove it, in the worst case it will be transformed to a tiebreaker |
346 | 379 | if (rsc.getFlags() != null && |
347 | 380 | rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) && |
348 | 381 | !rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) { |
349 | 382 | ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName); |
350 | 383 | logLinstorAnswers(delAnswers); |
351 | 384 | } |
352 | | - |
353 | | - // remove allow-two-primaries |
354 | | - ResourceDefinitionModify rdm = new ResourceDefinitionModify(); |
355 | | - rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries")); |
356 | | - ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm); |
357 | | - if (answers.hasError()) { |
358 | | - s_logger.error( |
359 | | - String.format("Failed to remove 'allow-two-primaries' on %s: %s", |
360 | | - rsc.getName(), LinstorUtil.getBestErrorMessage(answers))); |
361 | | - // do not fail here as removing allow-two-primaries property isn't fatal |
362 | | - } |
363 | 385 | } catch (ApiException apiEx) { |
364 | 386 | s_logger.error(apiEx.getBestMessage()); |
365 | 387 | // do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal |
|
0 commit comments