|
16 | 16 | // under the License. |
17 | 17 | package com.cloud.hypervisor.kvm.storage; |
18 | 18 |
|
| 19 | +import java.util.ArrayList; |
19 | 20 | import java.util.Collections; |
20 | 21 | import java.util.HashMap; |
21 | 22 | import java.util.List; |
|
26 | 27 |
|
27 | 28 | import com.cloud.storage.Storage; |
28 | 29 | import com.cloud.utils.exception.CloudRuntimeException; |
| 30 | + |
29 | 31 | import org.apache.cloudstack.storage.datastore.util.LinstorUtil; |
30 | 32 | import org.apache.cloudstack.utils.qemu.QemuImg; |
31 | 33 | import org.apache.cloudstack.utils.qemu.QemuImgException; |
|
44 | 46 | import com.linbit.linstor.api.model.Properties; |
45 | 47 | import com.linbit.linstor.api.model.ProviderKind; |
46 | 48 | import com.linbit.linstor.api.model.Resource; |
| 49 | +import com.linbit.linstor.api.model.ResourceConnectionModify; |
47 | 50 | import com.linbit.linstor.api.model.ResourceDefinition; |
48 | | -import com.linbit.linstor.api.model.ResourceDefinitionModify; |
49 | 51 | import com.linbit.linstor.api.model.ResourceGroupSpawn; |
50 | 52 | import com.linbit.linstor.api.model.ResourceMakeAvailable; |
51 | 53 | import com.linbit.linstor.api.model.ResourceWithVolumes; |
@@ -242,15 +244,19 @@ public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, Qemu |
242 | 244 | * @throws ApiException if any problem connecting to the Linstor controller |
243 | 245 | */ |
244 | 246 | private void allow2PrimariesIfInUse(DevelopersApi api, String rscName) throws ApiException { |
245 | | - if (LinstorUtil.isResourceInUse(api, rscName)) { |
| 247 | + String inUseNode = LinstorUtil.isResourceInUse(api, rscName); |
| 248 | + if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) { |
246 | 249 | // allow 2 primaries for live migration, should be removed by disconnect on the other end |
247 | | - ResourceDefinitionModify rdm = new ResourceDefinitionModify(); |
| 250 | + ResourceConnectionModify rcm = new ResourceConnectionModify(); |
248 | 251 | Properties props = new Properties(); |
249 | 252 | props.put("DrbdOptions/Net/allow-two-primaries", "yes"); |
250 | | - rdm.setOverrideProps(props); |
251 | | - ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm); |
| 253 | + props.put("DrbdOptions/Net/protocol", "C"); |
| 254 | + rcm.setOverrideProps(props); |
| 255 | + ApiCallRcList answers = api.resourceConnectionModify(rscName, inUseNode, localNodeName, rcm); |
252 | 256 | if (answers.hasError()) { |
253 | | - logger.error("Unable to set 'allow-two-primaries' on {} ", rscName); |
| 257 | + logger.error(String.format( |
| 258 | + "Unable to set protocol C and 'allow-two-primaries' on %s/%s/%s", |
| 259 | + inUseNode, localNodeName, rscName)); |
254 | 260 | // do not fail here as adding allow-two-primaries property is only a problem while live migrating |
255 | 261 | } |
256 | 262 | } |
@@ -290,6 +296,23 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S |
290 | 296 | return true; |
291 | 297 | } |
292 | 298 |
|
| 299 | + private void removeTwoPrimariesRcProps(DevelopersApi api, String inUseNode, String rscName) throws ApiException { |
| 300 | + ResourceConnectionModify rcm = new ResourceConnectionModify(); |
| 301 | + List<String> deleteProps = new ArrayList<>(); |
| 302 | + deleteProps.add("DrbdOptions/Net/allow-two-primaries"); |
| 303 | + deleteProps.add("DrbdOptions/Net/protocol"); |
| 304 | + rcm.deleteProps(deleteProps); |
| 305 | + ApiCallRcList answers = api.resourceConnectionModify(rscName, localNodeName, inUseNode, rcm); |
| 306 | + if (answers.hasError()) { |
| 307 | + s_logger.error( |
| 308 | + String.format("Failed to remove 'protocol' and 'allow-two-primaries' on %s/%s/%s: %s", |
| 309 | + localNodeName, |
| 310 | + inUseNode, |
| 311 | + rscName, LinstorUtil.getBestErrorMessage(answers))); |
| 312 | + // do not fail here as removing allow-two-primaries property isn't fatal |
| 313 | + } |
| 314 | + } |
| 315 | + |
293 | 316 | private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool) |
294 | 317 | { |
295 | 318 | if (volumePath == null) { |
@@ -319,27 +342,25 @@ private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool) |
319 | 342 |
|
320 | 343 |
|
321 | 344 | if (optRsc.isPresent()) { |
| 345 | + Resource rsc = optRsc.get(); |
322 | 346 | try { |
323 | | - Resource rsc = optRsc.get(); |
| 347 | + String inUseNode = LinstorUtil.isResourceInUse(api, rsc.getName()); |
| 348 | + if (inUseNode != null && !inUseNode.equalsIgnoreCase(localNodeName)) { |
| 349 | + removeTwoPrimariesRcProps(api, inUseNode, rsc.getName()); |
| 350 | + } |
| 351 | + } catch (ApiException apiEx) { |
| 352 | + s_logger.error(apiEx.getBestMessage()); |
| 353 | + // do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal |
| 354 | + } |
324 | 355 |
|
| 356 | + try { |
325 | 357 | // if diskless resource remove it, in the worst case it will be transformed to a tiebreaker |
326 | 358 | if (rsc.getFlags() != null && |
327 | 359 | rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) && |
328 | 360 | !rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) { |
329 | 361 | ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName); |
330 | 362 | logLinstorAnswers(delAnswers); |
331 | 363 | } |
332 | | - |
333 | | - // remove allow-two-primaries |
334 | | - ResourceDefinitionModify rdm = new ResourceDefinitionModify(); |
335 | | - rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries")); |
336 | | - ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm); |
337 | | - if (answers.hasError()) { |
338 | | - logger.error( |
339 | | - String.format("Failed to remove 'allow-two-primaries' on %s: %s", |
340 | | - rsc.getName(), LinstorUtil.getBestErrorMessage(answers))); |
341 | | - // do not fail here as removing allow-two-primaries property isn't fatal |
342 | | - } |
343 | 364 | } catch (ApiException apiEx) { |
344 | 365 | logger.error(apiEx.getBestMessage()); |
345 | 366 | // do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal |
|
0 commit comments