Skip to content

Commit 4855ba7

Browse files
committed
linstor: cleanup diskless nodes on disconnect
If disconnect is running on a diskless node, try to cleanup the resource.
1 parent 6cd5c6a commit 4855ba7

1 file changed

Lines changed: 74 additions & 40 deletions

File tree

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())
@@ -303,23 +308,90 @@ public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<S
303308
return true;
304309
}
305310

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

313383
@Override
314384
public boolean disconnectPhysicalDisk(Map<String, String> volumeToDisconnect)
315385
{
386+
// as of now this is only relevant for iscsi targets
387+
s_logger.info("Linstor: disconnectPhysicalDisk(Map<String, String> volumeToDisconnect) called?");
316388
return false;
317389
}
318390

319391
private Optional<ResourceWithVolumes> getResourceByPath(final List<ResourceWithVolumes> resources, String path) {
320392
return resources.stream()
321393
.filter(rsc -> rsc.getVolumes().stream()
322-
.anyMatch(v -> v.getDevicePath().equals(path)))
394+
.anyMatch(v -> path.equals(v.getDevicePath())))
323395
.findFirst();
324396
}
325397

@@ -340,46 +412,8 @@ public boolean disconnectPhysicalDiskByPath(String localPath)
340412
s_logger.debug("Linstor: disconnectPhysicalDiskByPath " + localPath);
341413
final KVMStoragePool pool = optFirstPool.get();
342414

343-
s_logger.debug("Linstor: Using storpool: " + pool.getUuid());
344-
final DevelopersApi api = getLinstorAPI(pool);
345-
346-
Optional<ResourceWithVolumes> optRsc;
347-
try {
348-
List<ResourceWithVolumes> resources = api.viewResources(
349-
Collections.singletonList(localNodeName),
350-
null,
351-
null,
352-
null,
353-
null,
354-
null);
355-
356-
optRsc = getResourceByPath(resources, localPath);
357-
} catch (ApiException apiEx) {
358-
// couldn't query linstor controller
359-
s_logger.error(apiEx.getBestMessage());
360-
return false;
361-
}
362-
363-
if (optRsc.isPresent()) {
364-
try {
365-
Resource rsc = optRsc.get();
366-
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
367-
rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
368-
ApiCallRcList answers = api.resourceDefinitionModify(rsc.getName(), rdm);
369-
if (answers.hasError()) {
370-
s_logger.error(
371-
String.format("Failed to remove 'allow-two-primaries' on %s: %s",
372-
rsc.getName(), LinstorUtil.getBestErrorMessage(answers)));
373-
// do not fail here as removing allow-two-primaries property isn't fatal
374-
}
375-
} catch(ApiException apiEx){
376-
s_logger.error(apiEx.getBestMessage());
377-
// do not fail here as removing allow-two-primaries property isn't fatal
378-
}
379-
return true;
380-
}
415+
return tryDisconnectLinstor(localPath, pool);
381416
}
382-
s_logger.info("Linstor: Couldn't find resource for this path: " + localPath);
383417
return false;
384418
}
385419

0 commit comments

Comments
 (0)