This is an automated email from the ASF dual-hosted git repository. dahn pushed a commit to branch 4.18 in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.18 by this push: new 2339412f734 linstor: make getDevicePath more robust (#9143) 2339412f734 is described below commit 2339412f73465aa2664d929bc4bdbdf629a87c22 Author: Rene Peinthor <rene.peint...@linbit.com> AuthorDate: Thu Jun 6 09:49:03 2024 +0200 linstor: make getDevicePath more robust (#9143) --- .../kvm/storage/LinstorStorageAdaptor.java | 24 ++++----------- .../driver/LinstorPrimaryDataStoreDriverImpl.java | 27 ++--------------- .../storage/datastore/util/LinstorUtil.java | 34 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java index 632b92c80fd..a3c283699a2 100644 --- a/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java +++ b/plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java @@ -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); diff --git a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java index d2d13eafc48..8b9b768d2a4 100644 --- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/driver/LinstorPrimaryDataStoreDriverImpl.java @@ -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); diff --git a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java index c8544fd3e3e..a23a26bd9dc 100644 --- a/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java +++ b/plugins/storage/volume/linstor/src/main/java/org/apache/cloudstack/storage/datastore/util/LinstorUtil.java @@ -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); + } }