From ddc51b7bd790236eab2d85c8bd4c9ee49d504ff9 Mon Sep 17 00:00:00 2001 From: Gabor Hernadi Date: Thu, 12 Dec 2019 15:09:41 +0100 Subject: [PATCH] Diskless: Fixing unnecessarily needed storagepools If a DRBD or a Writecache layer is configure above an nvme, the target resource will not create the LV for external metadata or writecache. However, until now, the target node also had to have the storagepool definied in the corresponding property ("StorPoolNameDrbdMeta" / "Writecache/PoolName"). Otherwise the controller reported an error which would have led to a nullpointer. --- .../layer/resource/RscDrbdLayerHelper.java | 46 ++++++++++++---- .../resource/RscWritecacheLayerHelper.java | 23 +++++--- .../StltLayerRscDataMerger.java | 12 +++-- .../StltLayerSnapDataMerger.java | 12 +++-- .../adapter/dmsetup/WritecacheLayer.java | 5 ++ .../storage/layer/adapter/drbd/DrbdLayer.java | 53 ++++++++++--------- server/proto/common/WritecacheRsc.proto | 2 +- .../ProtoCommonSerializerBuilder.java | 7 ++- .../linbit/linstor/core/objects/Volume.java | 5 +- .../data/adapter/drbd/DrbdVlmData.java | 9 +++- .../adapter/writecache/WritecacheVlmData.java | 2 +- 11 files changed, 121 insertions(+), 55 deletions(-) diff --git a/controller/src/main/java/com/linbit/linstor/layer/resource/RscDrbdLayerHelper.java b/controller/src/main/java/com/linbit/linstor/layer/resource/RscDrbdLayerHelper.java index da80ce981..caecb55be 100644 --- a/controller/src/main/java/com/linbit/linstor/layer/resource/RscDrbdLayerHelper.java +++ b/controller/src/main/java/com/linbit/linstor/layer/resource/RscDrbdLayerHelper.java @@ -267,6 +267,12 @@ protected boolean needsChildVlm(AbsRscLayerObject childRscDataRef, Vol return needsChild; } + private boolean isDrbdDiskless(AbsRscLayerObject childRscDataRef) throws AccessDeniedException + { + return childRscDataRef.getAbsResource().getStateFlags() + .isSet(apiCtx, Resource.Flags.DRBD_DISKLESS); + } + @Override protected DrbdVlmData createVlmLayerData( DrbdRscData drbdRscData, @@ -282,7 +288,11 @@ protected DrbdVlmData createVlmLayerData( drbdRscData.getResourceNameSuffix(), payload ); - StorPool extMetaStorPool = getExternalMetaDiskStorPool(vlm); + StorPool extMetaStorPool = null; + if (needsMetaData(drbdRscData, layerListRef)) + { + extMetaStorPool = getExternalMetaDiskStorPool(vlm); + } DrbdVlmData drbdVlmData = layerDataFactory.createDrbdVlmData( vlm, extMetaStorPool, @@ -383,6 +393,30 @@ protected List getChildRsc( List layerListRef ) throws AccessDeniedException, InvalidKeyException + { + List ret = new ArrayList<>(); + + if (isDrbdDiskless(rscDataRef)) + { + ret.add(new ChildResourceData("", DeviceLayerKind.STORAGE)); + } + else + { + ret.add(new ChildResourceData("")); + } + + if (needsMetaData(rscDataRef, layerListRef)) + { + ret.add(new ChildResourceData(DrbdRscData.SUFFIX_META, DeviceLayerKind.STORAGE)); + } + + return ret; + } + + private boolean needsMetaData( + DrbdRscData rscDataRef, + List layerListRef + ) throws AccessDeniedException { boolean allVlmsUseInternalMetaData = true; Resource rsc = rscDataRef.getAbsResource(); @@ -410,20 +444,12 @@ protected List getChildRsc( } } - List ret = new ArrayList<>(); - ret.add(new ChildResourceData("")); // always have data - boolean isNvmeBelow = layerListRef.contains(DeviceLayerKind.NVME); boolean isNvmeInitiator = rscDataRef.getAbsResource().getStateFlags() .isSet(apiCtx, Resource.Flags.NVME_INITIATOR); boolean isDrbdDiskless = rsc.getStateFlags().isSet(apiCtx, Resource.Flags.DRBD_DISKLESS); - if (!allVlmsUseInternalMetaData && !isDrbdDiskless && (!isNvmeBelow || isNvmeInitiator)) - { - ret.add(new ChildResourceData(DrbdRscData.SUFFIX_META, DeviceLayerKind.STORAGE)); - } - - return ret; + return !allVlmsUseInternalMetaData && !isDrbdDiskless && (!isNvmeBelow || isNvmeInitiator); } @Override diff --git a/controller/src/main/java/com/linbit/linstor/layer/resource/RscWritecacheLayerHelper.java b/controller/src/main/java/com/linbit/linstor/layer/resource/RscWritecacheLayerHelper.java index d5b3e2ba3..c346d573d 100644 --- a/controller/src/main/java/com/linbit/linstor/layer/resource/RscWritecacheLayerHelper.java +++ b/controller/src/main/java/com/linbit/linstor/layer/resource/RscWritecacheLayerHelper.java @@ -151,8 +151,12 @@ protected WritecacheVlmData createVlmLayerData( throws AccessDeniedException, DatabaseException, ValueOutOfRangeException, ExhaustedPoolException, ValueInUseException, LinStorException { - - return layerDataFactory.createWritecacheVlmData(vlm, getCacheStorPool(vlm), writecacheRscData); + StorPool cacheStorPool = null; + if (needsCacheDevice(writecacheRscData, layerListRef)) + { + cacheStorPool = getCacheStorPool(vlm); + } + return layerDataFactory.createWritecacheVlmData(vlm, cacheStorPool, writecacheRscData); } @Override @@ -178,10 +182,7 @@ protected List getChildRsc( List children = new ArrayList<>(); children.add(new ChildResourceData(WritecacheRscData.SUFFIX_DATA)); - boolean isNvmeBelow = layerListRef.contains(DeviceLayerKind.NVME); - boolean isNvmeInitiator = rscDataRef.getAbsResource().getStateFlags() - .isSet(apiCtx, Resource.Flags.NVME_INITIATOR); - if (!isNvmeBelow || isNvmeInitiator) + if (needsCacheDevice(rscDataRef, layerListRef)) { children.add(new ChildResourceData(WritecacheRscData.SUFFIX_CACHE, DeviceLayerKind.STORAGE)); } @@ -189,6 +190,16 @@ protected List getChildRsc( return children; } + private boolean needsCacheDevice(WritecacheRscData rscDataRef, List layerListRef) + throws AccessDeniedException + { + boolean isNvmeBelow = layerListRef.contains(DeviceLayerKind.NVME); + boolean isNvmeInitiator = rscDataRef.getAbsResource().getStateFlags() + .isSet(apiCtx, Resource.Flags.NVME_INITIATOR); + boolean needsCacheDevice = !isNvmeBelow || isNvmeInitiator; + return needsCacheDevice; + } + @Override public StorPool getStorPool(Volume vlmRef, AbsRscLayerObject childRef) throws AccessDeniedException, InvalidKeyException, InvalidNameException diff --git a/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerRscDataMerger.java b/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerRscDataMerger.java index 17264e87d..22dada7c3 100644 --- a/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerRscDataMerger.java +++ b/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerRscDataMerger.java @@ -645,10 +645,14 @@ protected void createWritecacheVlm( ) throws AccessDeniedException, InvalidNameException { String cacheStorPoolNameStr = vlmPojo.getCacheStorPoolName(); - StorPool cacheStorPool = vlmRef.getAbsResource().getNode().getStorPool( - apiCtx, - new StorPoolName(cacheStorPoolNameStr) - ); + StorPool cacheStorPool = null; + if (cacheStorPoolNameStr != null && !cacheStorPoolNameStr.trim().isEmpty()) + { + cacheStorPool = vlmRef.getAbsResource().getNode().getStorPool( + apiCtx, + new StorPoolName(cacheStorPoolNameStr) + ); + } WritecacheVlmData writecacheVlmData = layerDataFactory.createWritecacheVlmData( vlmRef, diff --git a/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerSnapDataMerger.java b/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerSnapDataMerger.java index bf4202b83..fa5a688a5 100644 --- a/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerSnapDataMerger.java +++ b/satellite/src/main/java/com/linbit/linstor/core/apicallhandler/StltLayerSnapDataMerger.java @@ -645,10 +645,14 @@ protected void createWritecacheVlm( ) throws AccessDeniedException, InvalidNameException { String cacheStorPoolNameStr = vlmPojoRef.getCacheStorPoolName(); - StorPool cacheStorPool = vlmRef.getAbsResource().getNode().getStorPool( - apiCtx, - new StorPoolName(cacheStorPoolNameStr) - ); + StorPool cacheStorPool = null; + if (cacheStorPoolNameStr != null && !cacheStorPoolNameStr.trim().isEmpty()) + { + cacheStorPool = vlmRef.getAbsResource().getNode().getStorPool( + apiCtx, + new StorPoolName(cacheStorPoolNameStr) + ); + } WritecacheVlmData writecacheVlmData = layerDataFactory.createWritecacheVlmData( vlmRef, diff --git a/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/dmsetup/WritecacheLayer.java b/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/dmsetup/WritecacheLayer.java index cbeb904e5..5f4c5cce7 100644 --- a/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/dmsetup/WritecacheLayer.java +++ b/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/dmsetup/WritecacheLayer.java @@ -124,6 +124,7 @@ public void prepare( { if (String.format(FORMAT_DEV_PATH, dmDev).equals(devicePath)) { + errorReporter.logTrace("Writecache: device exists: %s, nothing to do", devicePath); exists = true; break; } @@ -135,6 +136,10 @@ public void prepare( vlmData.setIdentifier(identifier); if (!exists) { + errorReporter.logTrace( + "Writecache: device not found. Will be created for identifier: %s", + identifier + ); vlmData.setDevicePath(null); } } diff --git a/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/drbd/DrbdLayer.java b/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/drbd/DrbdLayer.java index 33a6cdaaa..c82ac3bb4 100644 --- a/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/drbd/DrbdLayer.java +++ b/satellite/src/main/java/com/linbit/linstor/storage/layer/adapter/drbd/DrbdLayer.java @@ -188,35 +188,40 @@ public void updateGrossSize(VlmProviderObject vlmData) long netSize = drbdVlmData.getUsableSize(); - if (drbdVlmData.isUsingExternalMetaData()) + boolean isDiskless = drbdVlmData.getRscLayerObject().getAbsResource().getStateFlags() + .isSet(workerCtx, Resource.Flags.DRBD_DISKLESS); + if (!isDiskless) { - long extMdSize = new MetaData().getExternalMdSize( - netSize, - peerSlots, - DrbdLayer.FIXME_AL_STRIPES, - DrbdLayer.FIXME_AL_STRIPE_SIZE - ); - drbdVlmData.setAllocatedSize(netSize + extMdSize); // rough estimation + if (drbdVlmData.isUsingExternalMetaData()) + { + long extMdSize = new MetaData().getExternalMdSize( + netSize, + peerSlots, + DrbdLayer.FIXME_AL_STRIPES, + DrbdLayer.FIXME_AL_STRIPE_SIZE + ); + drbdVlmData.setAllocatedSize(netSize + extMdSize); // rough estimation - drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_DATA).setUsableSize(netSize); - VlmProviderObject metaChild = drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_META); - if (metaChild != null) + drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_DATA).setUsableSize(netSize); + VlmProviderObject metaChild = drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_META); + if (metaChild != null) + { + // is null if we are nvme-traget while the drbd-ext-metadata stays on the initiator side + metaChild.setUsableSize(extMdSize); + } + } + else { - // is null if we are nvme-traget while the drbd-ext-metadata stays on the initiator side - metaChild.setUsableSize(extMdSize); + long grossSize = new MetaData().getGrossSize( + netSize, + peerSlots, + DrbdLayer.FIXME_AL_STRIPES, + DrbdLayer.FIXME_AL_STRIPE_SIZE + ); + drbdVlmData.setAllocatedSize(grossSize); + drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_DATA).setUsableSize(grossSize); } } - else - { - long grossSize = new MetaData().getGrossSize( - netSize, - peerSlots, - DrbdLayer.FIXME_AL_STRIPES, - DrbdLayer.FIXME_AL_STRIPE_SIZE - ); - drbdVlmData.setAllocatedSize(grossSize); - drbdVlmData.getChildBySuffix(DrbdRscData.SUFFIX_DATA).setUsableSize(grossSize); - } } catch (InvalidKeyException | IllegalArgumentException | MinSizeException | MaxSizeException | MinAlSizeException | MaxAlSizeException | AlStripesException | PeerCountException exc) diff --git a/server/proto/common/WritecacheRsc.proto b/server/proto/common/WritecacheRsc.proto index 518bc8985..e6d735158 100644 --- a/server/proto/common/WritecacheRsc.proto +++ b/server/proto/common/WritecacheRsc.proto @@ -17,6 +17,6 @@ message WritecacheVlm optional int64 allocated_size = 4; optional int64 usable_size = 5; optional string disk_state = 6; - required string cache_stor_pool_name = 7; + optional string cache_stor_pool_name = 7; } diff --git a/server/src/main/java/com/linbit/linstor/api/protobuf/serializer/ProtoCommonSerializerBuilder.java b/server/src/main/java/com/linbit/linstor/api/protobuf/serializer/ProtoCommonSerializerBuilder.java index 2dc1c8c2b..1fe7c0288 100644 --- a/server/src/main/java/com/linbit/linstor/api/protobuf/serializer/ProtoCommonSerializerBuilder.java +++ b/server/src/main/java/com/linbit/linstor/api/protobuf/serializer/ProtoCommonSerializerBuilder.java @@ -1439,8 +1439,7 @@ private static WritecacheVlm buildWritecacheVlm(WritecacheVlmPojo vlmPojo) WritecacheVlm.Builder protoVlmBuilder = WritecacheVlm.newBuilder() .setVlmNr(vlmPojo.getVlmNr()) .setAllocatedSize(vlmPojo.getAllocatedSize()) - .setUsableSize(vlmPojo.getUsableSize()) - .setCacheStorPoolName(vlmPojo.getCacheStorPoolName()); + .setUsableSize(vlmPojo.getUsableSize()); if (vlmPojo.getDevicePath() != null) { protoVlmBuilder.setDevicePathData(vlmPojo.getDevicePath()); @@ -1453,6 +1452,10 @@ private static WritecacheVlm buildWritecacheVlm(WritecacheVlmPojo vlmPojo) { protoVlmBuilder.setDiskState(vlmPojo.getDiskState()); } + if (vlmPojo.getCacheStorPoolName() != null) + { + protoVlmBuilder.setCacheStorPoolName(vlmPojo.getCacheStorPoolName()); + } return protoVlmBuilder.build(); } diff --git a/server/src/main/java/com/linbit/linstor/core/objects/Volume.java b/server/src/main/java/com/linbit/linstor/core/objects/Volume.java index 63d98509d..6879e191c 100644 --- a/server/src/main/java/com/linbit/linstor/core/objects/Volume.java +++ b/server/src/main/java/com/linbit/linstor/core/objects/Volume.java @@ -379,9 +379,10 @@ public VolumeApi getApiData(Long allocated, AccessContext accCtx) throws AccessD { AbsRscLayerObject rscLayerObject = rscLayersToExpand.removeFirst(); VlmProviderObject vlmProvider = rscLayerObject.getVlmLayerObjects().get(vlmNr); + if (vlmProvider != null) { - // vlmProvider is null is a layer (like DRBD) does not need for all volumes backing vlmProvider + // vlmProvider is null as a layer (like DRBD) does not need for all volumes backing vlmProvider // (like in the case of mixed internal and external meta-data) layerDataList.add( new Pair<>( @@ -392,7 +393,7 @@ public VolumeApi getApiData(Long allocated, AccessContext accCtx) throws AccessD } // deprecated - only for compatibility with old versions - if (rscLayerObject.getResourceNameSuffix().isEmpty()) // for "" resources vlmProvider always have to exist + if (compatStorPool == null && rscLayerObject.getResourceNameSuffix().isEmpty()) { compatStorPool = vlmProvider.getStorPool(); } diff --git a/server/src/main/java/com/linbit/linstor/storage/data/adapter/drbd/DrbdVlmData.java b/server/src/main/java/com/linbit/linstor/storage/data/adapter/drbd/DrbdVlmData.java index 1f99ab4ee..e3e9ad970 100644 --- a/server/src/main/java/com/linbit/linstor/storage/data/adapter/drbd/DrbdVlmData.java +++ b/server/src/main/java/com/linbit/linstor/storage/data/adapter/drbd/DrbdVlmData.java @@ -199,7 +199,14 @@ public boolean isUsingExternalMetaData() @Override public String getBackingDevice() { - return getChildBySuffix(DrbdRscData.SUFFIX_DATA).getDevicePath(); + VlmProviderObject childBySuffix = getChildBySuffix(DrbdRscData.SUFFIX_DATA); + String devicePath = null; + if (childBySuffix != null) + { + // null when diskless + devicePath = childBySuffix.getDevicePath(); + } + return devicePath; } @Override diff --git a/server/src/main/java/com/linbit/linstor/storage/data/adapter/writecache/WritecacheVlmData.java b/server/src/main/java/com/linbit/linstor/storage/data/adapter/writecache/WritecacheVlmData.java index f51fa2094..88cd041d9 100644 --- a/server/src/main/java/com/linbit/linstor/storage/data/adapter/writecache/WritecacheVlmData.java +++ b/server/src/main/java/com/linbit/linstor/storage/data/adapter/writecache/WritecacheVlmData.java @@ -208,7 +208,7 @@ public WritecacheVlmPojo asPojo(AccessContext accCtxRef) throws AccessDeniedExce getVlmNr().value, devicePathData, devicePathCache, - cacheStorPool.getName().displayValue, + cacheStorPool == null ? null : cacheStorPool.getName().displayValue, allocatedSize, usableSize, diskState