linstor: make getDevicePath more robust (#9143)

This commit is contained in:
Rene Peinthor 2024-06-06 09:49:03 +02:00 committed by GitHub
parent c791c138e7
commit 2339412f73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 42 deletions

View File

@ -157,24 +157,12 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
List<VolumeDefinition> volumeDefs = api.volumeDefinitionList(rscName, null, null);
final long size = volumeDefs.isEmpty() ? 0 : volumeDefs.get(0).getSizeKib() * 1024;
List<ResourceWithVolumes> resources = api.viewResources(
Collections.emptyList(),
Collections.singletonList(rscName),
Collections.emptyList(),
null,
null,
null);
if (!resources.isEmpty() && !resources.get(0).getVolumes().isEmpty()) {
final String devPath = resources.get(0).getVolumes().get(0).getDevicePath();
final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devPath, name, pool);
kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
kvmDisk.setSize(size);
kvmDisk.setVirtualSize(size);
return kvmDisk;
} else {
s_logger.error("Linstor: viewResources didn't return resources or volumes for " + rscName);
throw new CloudRuntimeException("Linstor: viewResources didn't return resources or volumes.");
}
final String devicePath = LinstorUtil.getDevicePath(api, rscName);
final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devicePath, name, pool);
kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
kvmDisk.setSize(size);
kvmDisk.setVirtualSize(size);
return kvmDisk;
} catch (ApiException apiEx) {
s_logger.error(apiEx);
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);

View File

@ -28,7 +28,6 @@ import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
import com.linbit.linstor.api.model.ResourceDefinitionCreate;
import com.linbit.linstor.api.model.ResourceDefinitionModify;
import com.linbit.linstor.api.model.ResourceGroupSpawn;
import com.linbit.linstor.api.model.ResourceWithVolumes;
import com.linbit.linstor.api.model.Snapshot;
import com.linbit.linstor.api.model.SnapshotRestore;
import com.linbit.linstor.api.model.VolumeDefinition;
@ -38,7 +37,6 @@ import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -315,25 +313,6 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
return answers.stream().filter(ApiCallRc::isError).findFirst().map(ApiCallRc::getMessage).orElse(null);
}
private String getDeviceName(DevelopersApi linstorApi, String rscName) throws ApiException {
List<ResourceWithVolumes> resources = linstorApi.viewResources(
Collections.emptyList(),
Collections.singletonList(rscName),
Collections.emptyList(),
null,
null,
null);
if (!resources.isEmpty() && !resources.get(0).getVolumes().isEmpty())
{
s_logger.info("Linstor: Created drbd device: " + resources.get(0).getVolumes().get(0).getDevicePath());
return resources.get(0).getVolumes().get(0).getDevicePath();
} else
{
s_logger.error("Linstor: viewResources didn't return resources or volumes.");
throw new CloudRuntimeException("Linstor: viewResources didn't return resources or volumes.");
}
}
private void applyQoSSettings(StoragePoolVO storagePool, DevelopersApi api, String rscName, Long maxIops)
throws ApiException
{
@ -420,7 +399,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
applyAuxProps(linstorApi, rscName, vol.getName(), vol.getAttachedVmName());
applyQoSSettings(storagePoolVO, linstorApi, rscName, vol.getMaxIops());
return getDeviceName(linstorApi, rscName);
return LinstorUtil.getDevicePath(linstorApi, rscName);
} catch (ApiException apiEx)
{
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
@ -473,7 +452,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
applyAuxProps(linstorApi, rscName, volumeInfo.getName(), volumeInfo.getAttachedVmName());
applyQoSSettings(storagePoolVO, linstorApi, rscName, volumeInfo.getMaxIops());
return getDeviceName(linstorApi, rscName);
return LinstorUtil.getDevicePath(linstorApi, rscName);
} catch (ApiException apiEx) {
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
@ -520,7 +499,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
applyAuxProps(linstorApi, rscName, volumeVO.getName(), null);
applyQoSSettings(storagePoolVO, linstorApi, rscName, volumeVO.getMaxIops());
return getDeviceName(linstorApi, rscName);
return LinstorUtil.getDevicePath(linstorApi, rscName);
} catch (ApiException apiEx) {
s_logger.error("Linstor: ApiEx - " + apiEx.getMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);

View File

@ -25,6 +25,7 @@ import com.linbit.linstor.api.model.ApiCallRcList;
import com.linbit.linstor.api.model.ProviderKind;
import com.linbit.linstor.api.model.Resource;
import com.linbit.linstor.api.model.ResourceGroup;
import com.linbit.linstor.api.model.ResourceWithVolumes;
import com.linbit.linstor.api.model.StoragePool;
import java.util.Collections;
@ -109,4 +110,37 @@ public class LinstorUtil {
s_logger.error("isResourceInUse: null returned from resourceList");
return false;
}
/**
* Try to get the device path for the given resource name.
* This could be made a bit more direct after java-linstor api is fixed for layer data subtypes.
* @param api developer api object to use
* @param rscName resource name to get the device path
* @return The device path of the resource.
* @throws ApiException if Linstor API call failed.
* @throws CloudRuntimeException if no device path could be found.
*/
public static String getDevicePath(DevelopersApi api, String rscName) throws ApiException, CloudRuntimeException {
List<ResourceWithVolumes> resources = api.viewResources(
Collections.emptyList(),
Collections.singletonList(rscName),
Collections.emptyList(),
null,
null,
null);
for (ResourceWithVolumes rsc : resources) {
if (!rsc.getVolumes().isEmpty()) {
// CloudStack resource always only have 1 volume
String devicePath = rsc.getVolumes().get(0).getDevicePath();
if (devicePath != null && !devicePath.isEmpty()) {
s_logger.debug(String.format("getDevicePath: %s -> %s", rscName, devicePath));
return devicePath;
}
}
}
final String errMsg = "viewResources didn't return resources or volumes for " + rscName;
s_logger.error(errMsg);
throw new CloudRuntimeException("Linstor: " + errMsg);
}
}