Skip to content

Commit

Permalink
linstor: make getDevicePath more robust
Browse files Browse the repository at this point in the history
Before we only asked the first resource for the device path,
if those resource was down or broken, we wouldn't get a device path at all.
Now we go through all resource and use the first device path we find,
as device path are always equal for all resources.
  • Loading branch information
rp- committed May 29, 2024
1 parent c791c13 commit 5a7e47d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,24 +157,12 @@ public KVMPhysicalDisk getPhysicalDisk(String name, KVMStoragePool pool)
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
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;
Expand All @@ -38,7 +37,6 @@
import javax.inject.Inject;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -315,25 +313,6 @@ private String checkLinstorAnswers(@Nonnull ApiCallRcList answers) {
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
{
Expand Down Expand Up @@ -420,7 +399,7 @@ private String createResource(VolumeInfo vol, StoragePoolVO storagePoolVO)
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());
Expand Down Expand Up @@ -473,7 +452,7 @@ private String cloneResource(long csCloneId, VolumeInfo volumeInfo, StoragePoolV
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);
Expand Down Expand Up @@ -520,7 +499,7 @@ private String createResourceFromSnapshot(long csSnapshotId, String rscName, Sto
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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;
Expand Down Expand Up @@ -109,4 +110,36 @@ public static boolean isResourceInUse(DevelopersApi api, String rscName) throws
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.info(String.format("getDevicePath: %s -> %s", rscName, devicePath));
return devicePath;
}
}
}

s_logger.error("viewResources didn't return resources or volumes for " + rscName);
throw new CloudRuntimeException("Linstor: viewResources didn't return resources or volumes for " + rscName);
}
}

0 comments on commit 5a7e47d

Please sign in to comment.