From 43ee12a6ea3443daecef5233f4208cbec5999dba Mon Sep 17 00:00:00 2001 From: OP Date: Mon, 20 Jul 2026 22:15:15 +0100 Subject: [PATCH] Exempt special satellites from the uname uniqueness check Since the uname map was introduced, only the first special satellite (e.g. EBS_TARGET) can authenticate: special satellites run within the controller's process, so they all report the controller's uname and every one after the first is de-authenticated with DUPLICATE_UNAME. This makes multi-AZ native EBS setups impossible to bootstrap. Special satellites never take part in DRBD, so the uname map (mapping DRBD peer unames to node names) does not apply to them. Skip the map update and the uniqueness check for special node types, mirroring the existing isSpecial() exemption for the node-name-mismatch info message in the same class. Fixes #505 --- .../CtrlAuthResponseApiCallHandler.java | 75 ++++++++++--------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/internal/CtrlAuthResponseApiCallHandler.java b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/internal/CtrlAuthResponseApiCallHandler.java index e6d7e0929..556f34283 100644 --- a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/internal/CtrlAuthResponseApiCallHandler.java +++ b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/internal/CtrlAuthResponseApiCallHandler.java @@ -120,47 +120,54 @@ private void updateUnameMap(Peer peer, String nodeUname) throws InvalidValueException, DatabaseException { Node node = peer.getNode(); - Props nodeProps = node.getProps(); - @Nullable String oldUname = nodeProps.getProp(InternalApiConsts.NODE_UNAME); - @Nullable NodeName curNodeName = nodeRepo.getUname(nodeUname); - if (!nodeUname.equals(oldUname)) + /* + * Special satellites run within the controller's process and therefore all report the + * controller's uname. They also never take part in DRBD, so the uname map (mapping DRBD + * peer unames to node names) does not apply to them. + */ + if (!node.getNodeType().isSpecial()) { - if (oldUname != null) + Props nodeProps = node.getProps(); + @Nullable String oldUname = nodeProps.getProp(InternalApiConsts.NODE_UNAME); + @Nullable NodeName curNodeName = nodeRepo.getUname(nodeUname); + if (!nodeUname.equals(oldUname)) { - // uname change, cleanup old uname - nodeRepo.removeUname(oldUname); - } - if (curNodeName != null) - { - peer.setAuthenticated(false); - peer.setConnectionStatus(ApiConsts.ConnectionStatus.DUPLICATE_UNAME); - errorReporter.reportError( - Level.ERROR, - new InvalidNameException( - String.format( - "Satellite has an uname '%s' that is already used by a different satellite '%s'", - nodeUname, - curNodeName), - nodeUname - ) - ); + if (oldUname != null) + { + // uname change, cleanup old uname + nodeRepo.removeUname(oldUname); + } + if (curNodeName != null) + { + peer.setAuthenticated(false); + peer.setConnectionStatus(ApiConsts.ConnectionStatus.DUPLICATE_UNAME); + errorReporter.reportError( + Level.ERROR, + new InvalidNameException( + String.format( + "Satellite has an uname '%s' that is already used by a different satellite '%s'", + nodeUname, + curNodeName), + nodeUname + ) + ); + } + else + { + // new node added + nodeProps.setProp(InternalApiConsts.NODE_UNAME, nodeUname); + nodeRepo.putUname(nodeUname, node.getName()); + } } else { - // new node added - nodeProps.setProp(InternalApiConsts.NODE_UNAME, nodeUname); - nodeRepo.putUname(nodeUname, node.getName()); - } - } - else - { - if (curNodeName == null) - { - // reconnect node - nodeRepo.putUname(nodeUname, node.getName()); + if (curNodeName == null) + { + // reconnect node + nodeRepo.putUname(nodeUname, node.getName()); + } } } - } private Flux authResponseInTransaction(