Linstor 4.19 fix selecting non enabled hosts (#8653)

* linstor: cleanup resource if copy from template failed

* linstor: do not use non enabled hosts for copy operations
This commit is contained in:
Rene Peinthor 2024-03-08 09:22:49 +01:00 committed by GitHub
parent d99b1b9c2d
commit 001c769054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 28 deletions

View File

@ -59,6 +59,7 @@ import com.cloud.api.storage.LinstorRevertBackupSnapshotCommand;
import com.cloud.configuration.Config;
import com.cloud.host.Host;
import com.cloud.host.dao.HostDao;
import com.cloud.resource.ResourceState;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ResizeVolumePayload;
import com.cloud.storage.SnapshotVO;
@ -214,6 +215,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
}
throw new CloudRuntimeException("Linstor: Unable to delete resource definition: " + rscDefName);
}
s_logger.info(String.format("Linstor: Deleted resource %s", rscDefName));
} catch (ApiException apiEx)
{
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
@ -865,7 +867,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
Host host = null;
for (String nodeName : linstorNodeNames) {
host = _hostDao.findByName(nodeName);
if (host != null) {
if (host != null && host.getResourceState() == ResourceState.Enabled) {
s_logger.info(String.format("Linstor: Make resource %s available on node %s ...", rscName, nodeName));
ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, nodeName, new ResourceMakeAvailable());
if (!answers.hasError()) {
@ -892,21 +894,16 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
}
private Optional<RemoteHostEndPoint> getDiskfullEP(DevelopersApi api, String rscName) throws ApiException {
com.linbit.linstor.api.model.StoragePool linSP =
LinstorUtil.getDiskfulStoragePool(api, rscName);
if (linSP != null)
{
Host host = _hostDao.findByName(linSP.getNodeName());
if (host == null)
{
s_logger.error("Linstor: Host '" + linSP.getNodeName() + "' not found.");
return Optional.empty();
}
else
{
return Optional.of(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
List<com.linbit.linstor.api.model.StoragePool> linSPs = LinstorUtil.getDiskfulStoragePools(api, rscName);
if (linSPs != null) {
for (com.linbit.linstor.api.model.StoragePool sp : linSPs) {
Host host = _hostDao.findByName(sp.getNodeName());
if (host != null && host.getResourceState() == ResourceState.Enabled) {
return Optional.of(RemoteHostEndPoint.getHypervisorHostEndPoint(host));
}
}
}
s_logger.error("Linstor: No diskfull host found.");
return Optional.empty();
}
@ -958,9 +955,11 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
}
else {
answer = new Answer(cmd, false, "Unable to get matching Linstor endpoint.");
deleteResourceDefinition(pool, rscName);
}
} catch (ApiException exc) {
s_logger.error("copy template failed: ", exc);
deleteResourceDefinition(pool, rscName);
throw new CloudRuntimeException(exc.getBestMessage());
}
return answer;

View File

@ -77,16 +77,16 @@ public class LinstorUtil {
return nodes.stream().map(Node::getName).collect(Collectors.toList());
}
public static com.linbit.linstor.api.model.StoragePool
getDiskfulStoragePool(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
public static List<com.linbit.linstor.api.model.StoragePool>
getDiskfulStoragePools(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
{
List<ResourceWithVolumes> resources = api.viewResources(
Collections.emptyList(),
Collections.singletonList(rscName),
Collections.emptyList(),
Collections.emptyList(),
null,
null);
Collections.emptyList(),
Collections.singletonList(rscName),
Collections.emptyList(),
Collections.emptyList(),
null,
null);
String nodeName = null;
String storagePoolName = null;
@ -107,13 +107,23 @@ public class LinstorUtil {
}
List<com.linbit.linstor.api.model.StoragePool> sps = api.viewStoragePools(
Collections.singletonList(nodeName),
Collections.singletonList(storagePoolName),
Collections.emptyList(),
null,
null
Collections.singletonList(nodeName),
Collections.singletonList(storagePoolName),
Collections.emptyList(),
null,
null
);
return !sps.isEmpty() ? sps.get(0) : null;
return sps != null ? sps : Collections.emptyList();
}
public static com.linbit.linstor.api.model.StoragePool
getDiskfulStoragePool(@Nonnull DevelopersApi api, @Nonnull String rscName) throws ApiException
{
List<com.linbit.linstor.api.model.StoragePool> sps = getDiskfulStoragePools(api, rscName);
if (sps != null) {
return !sps.isEmpty() ? sps.get(0) : null;
}
return null;
}
public static String getSnapshotPath(com.linbit.linstor.api.model.StoragePool sp, String rscName, String snapshotName) {