Skip to content

Commit 9d5d4e5

Browse files
authored
linstor: cleanup diskless nodes on disconnect (#8790)
1 parent eead271 commit 9d5d4e5

File tree

1 file changed

+74
-40
lines changed

1 file changed

+74
-40
lines changed

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

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.cloud.storage.Storage;
3939
import com.cloud.utils.exception.CloudRuntimeException;
4040
import com.linbit.linstor.api.ApiClient;
41+
import com.linbit.linstor.api.ApiConsts;
4142
import com.linbit.linstor.api.ApiException;
4243
import com.linbit.linstor.api.Configuration;
4344
import com.linbit.linstor.api.DevelopersApi;
@@ -103,6 +104,10 @@ private void logLinstorAnswer(@Nonnull ApiCallRc answer) {
103104
}
104105
}
105106

107+
private void logLinstorAnswers(@Nonnull ApiCallRcList answers) {
108+
answers.forEach(this::logLinstorAnswer);
109+
}
110+
106111
private void checkLinstorAnswersThrow(@Nonnull ApiCallRcList answers) {
107112
answers.forEach(this::logLinstorAnswer);
108113
if (answers.hasError())
@@ -316,23 +321,90 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S
316321
return true;
317322
}
318323

324+
private boolean tryDisconnectLinstor(String volumePath, KVMStoragePool pool)
325+
{
326+
if (volumePath == null) {
327+
return false;
328+
}
329+
330+
s_logger.debug("Linstor: Using storage pool: " + pool.getUuid());
331+
final DevelopersApi api = getLinstorAPI(pool);
332+
333+
Optional<ResourceWithVolumes> optRsc;
334+
try
335+
{
336+
List<ResourceWithVolumes> resources = api.viewResources(
337+
Collections.singletonList(localNodeName),
338+
null,
339+
null,
340+
null,
341+
null,
342+
null);
343+
344+
optRsc = getResourceByPath(resources, volumePath);
345+
} catch (ApiException apiEx) {
346+
// couldn't query linstor controller
347+
s_logger.error(apiEx.getBestMessage());
348+
return false;
349+
}
350+
351+
352+
if (optRsc.isPresent()) {
353+
try {
354+
Resource rsc = optRsc.get();
355+
356+
// if diskless resource remove it, in the worst case it will be transformed to a tiebreaker
357+
if (rsc.getFlags() != null &&
358+
rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) &&
359+
!rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) {
360+
ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName);
361+
logLinstorAnswers(delAnswers);
362+
}
363+
364+
// remove allow-two-primaries
365+
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
366+
rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
367+
ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm);
368+
if (answers.hasError()) {
369+
s_logger.error(
370+
String.format("Failed to remove 'allow-two-primaries' on %s: %s",
371+
rsc.getName(), LinstorUtil.getBestErrorMessage(answers)));
372+
// do not fail here as removing allow-two-primaries property isn't fatal
373+
}
374+
} catch (ApiException apiEx) {
375+
s_logger.error(apiEx.getBestMessage());
376+
// do not fail here as removing allow-two-primaries property or deleting diskless isn't fatal
377+
}
378+
379+
return true;
380+
}
381+
382+
s_logger.warn("Linstor: Couldn't find resource for this path: " + volumePath);
383+
return false;
384+
}
385+
319386
@Override
320387
public boolean disconnectPhysicalDisk(String volumePath, KVMStoragePool pool)
321388
{
322389
s_logger.debug("Linstor: disconnectPhysicalDisk " + pool.getUuid() + ":" + volumePath);
390+
if (MapStorageUuidToStoragePool.containsValue(pool)) {
391+
return tryDisconnectLinstor(volumePath, pool);
392+
}
323393
return false;
324394
}
325395

326396
@Override
327397
public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect)
328398
{
399+
// as of now this is only relevant for iscsi targets
400+
s_logger.info("Linstor: disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) called?");
329401
return false;
330402
}
331403

332404
private Optional<ResourceWithVolumes> getResourceByPath(final List<ResourceWithVolumes> resources, String path) {
333405
return resources.stream()
334406
.filter(rsc -> rsc.getVolumes().stream()
335-
.anyMatch(v -> v.getDevicePath().equals(path)))
407+
.anyMatch(v -> path.equals(v.getDevicePath())))
336408
.findFirst();
337409
}
338410

@@ -353,46 +425,8 @@ public boolean disconnectPhysicalDiskByPath(String localPath)
353425
s_logger.debug("Linstor: disconnectPhysicalDiskByPath " + localPath);
354426
final KVMStoragePool pool = optFirstPool.get();
355427

356-
s_logger.debug("Linstor: Using storpool: " + pool.getUuid());
357-
final DevelopersApi api = getLinstorAPI(pool);
358-
359-
Optional<ResourceWithVolumes> optRsc;
360-
try {
361-
List<ResourceWithVolumes> resources = api.viewResources(
362-
Collections.singletonList(localNodeName),
363-
null,
364-
null,
365-
null,
366-
null,
367-
null);
368-
369-
optRsc = getResourceByPath(resources, localPath);
370-
} catch (ApiException apiEx) {
371-
// couldn't query linstor controller
372-
s_logger.error(apiEx.getBestMessage());
373-
return false;
374-
}
375-
376-
if (optRsc.isPresent()) {
377-
try {
378-
Resource rsc = optRsc.get();
379-
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
380-
rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
381-
ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm);
382-
if (answers.hasError()) {
383-
s_logger.error(
384-
String.format("Failed to remove 'allow-two-primaries' on %s: %s",
385-
rsc.getName(), LinstorUtil.getBestErrorMessage(answers)));
386-
// do not fail here as removing allow-two-primaries property isn't fatal
387-
}
388-
} catch(ApiException apiEx){
389-
s_logger.error(apiEx.getBestMessage());
390-
// do not fail here as removing allow-two-primaries property isn't fatal
391-
}
392-
return true;
393-
}
428+
return tryDisconnectLinstor(localPath, pool);
394429
}
395-
s_logger.info("Linstor: Couldn't find resource for this path: " + localPath);
396430
return false;
397431
}
398432

0 commit comments

Comments
 (0)