Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,19 @@ private boolean deRefOrDeleteResource(DevelopersApi api, String rscName, String
// if there is only one template-for property left for templates, the template isn't needed anymore
// or if it isn't a template anyway, it will not have this Aux property
// _cs-template-for- properties work like a ref-count.
if (rd.getProps().keySet().stream()
long remainingTemplateRefs = rd.getProps().keySet().stream()
.filter(key -> key.startsWith("Aux/" + LinstorUtil.CS_TEMPLATE_FOR_PREFIX))
.count() == expectedProps) {
.count();
if (remainingTemplateRefs == expectedProps) {
// Surface the legacy case where a resource has zero `_cs-template-for-` aux
// properties even though we never decremented one — that's a template predating
// the ref-count convention, or a stale orphan. Logging before deletion lets
// operators audit how many such orphans existed at upgrade time.
if (expectedProps == 0) {
logger.info("Linstor: deleting resource {} which has no _cs-template-for- aux properties " +
"(legacy template predating the ref-count convention, or a stale orphan). " +
"Resource group context: {}", rd.getName(), rscGrpName);
}
ApiCallRcList answers = api.resourceDefinitionDelete(rd.getName());
checkLinstorAnswersThrow(answers);
deleted = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,26 @@ public static ResourceDefinition findResourceDefinition(DevelopersApi api, Strin
.filter(rscDfn -> rscDfn.getProps().containsKey(LinstorUtil.getTemplateForAuxPropKey(rscGrpName)))
.findFirst();

return rd.orElseGet(() -> rdsStartingWith.get(0));
if (rd.isPresent()) {
return rd.get();
}
// Fallback: no resource has the exact "_cs-template-for-<rscGrpName>" property.
// This happens when (a) the matched resource is a legacy template created before that
// convention was introduced, or (b) the template was cached by a different resource
// group and the operator hopes to share it. Log so the ambiguity is visible — silent
// first-match selection has previously routed clones to the wrong template when
// multiple resource groups coexisted on the same controller.
ResourceDefinition fallback = rdsStartingWith.get(0);
LOGGER.warn("LINSTOR findResourceDefinition: no resource for '{}' has the expected " +
"Aux property '{}' for resource group '{}'; falling back to first match '{}' " +
"(present aux properties: {}). If this is wrong, set the property explicitly " +
"or remove the unrelated resource definition.",
rscName, getTemplateForAuxPropKey(rscGrpName), rscGrpName,
fallback.getName(),
fallback.getProps().keySet().stream()
.filter(k -> k.startsWith("Aux/" + CS_TEMPLATE_FOR_PREFIX))
.collect(Collectors.toList()));
return fallback;
}

public static boolean isRscDiskless(ResourceWithVolumes rsc) {
Expand Down