From a50acc34bc495ab7b915fc3421fb616151e3c7c2 Mon Sep 17 00:00:00 2001 From: kkewwei Date: Thu, 20 Jun 2024 22:13:23 +0800 Subject: [PATCH] Fix the computed max shards of cluster to avoid int overflow (#14155) Signed-off-by: kkewwei --- CHANGELOG.md | 1 + .../indices/ShardLimitValidator.java | 7 ++++--- .../indices/ShardLimitValidatorTests.java | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c3e63e36bc82..cfeb02d5a7b06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed - Fix handling of Short and Byte data types in ScriptProcessor ingest pipeline ([#14379](https://github.com/opensearch-project/OpenSearch/issues/14379)) - Switch to iterative version of WKT format parser ([#14086](https://github.com/opensearch-project/OpenSearch/pull/14086)) +- Fix the computed max shards of cluster to avoid int overflow ([#14155](https://github.com/opensearch-project/OpenSearch/pull/14155)) ### Security diff --git a/server/src/main/java/org/opensearch/indices/ShardLimitValidator.java b/server/src/main/java/org/opensearch/indices/ShardLimitValidator.java index e345b613eebbd..94e91e2d4c3ac 100644 --- a/server/src/main/java/org/opensearch/indices/ShardLimitValidator.java +++ b/server/src/main/java/org/opensearch/indices/ShardLimitValidator.java @@ -261,14 +261,15 @@ static Optional checkShardLimit( return Optional.empty(); } + int computedMaxShards = (int) Math.min(Integer.MAX_VALUE, (long) maxShardsPerNodeSetting * nodeCount); int maxShardsInCluster = maxShardsPerClusterSetting; if (maxShardsInCluster == -1) { - maxShardsInCluster = maxShardsPerNodeSetting * nodeCount; + maxShardsInCluster = computedMaxShards; } else { - maxShardsInCluster = Math.min(maxShardsInCluster, maxShardsPerNodeSetting * nodeCount); + maxShardsInCluster = Math.min(maxShardsInCluster, computedMaxShards); } - int currentOpenShards = state.getMetadata().getTotalOpenIndexShards(); + long currentOpenShards = state.getMetadata().getTotalOpenIndexShards(); if ((currentOpenShards + newShards) > maxShardsInCluster) { String errorMessage = "this action would add [" + newShards diff --git a/server/src/test/java/org/opensearch/indices/ShardLimitValidatorTests.java b/server/src/test/java/org/opensearch/indices/ShardLimitValidatorTests.java index 040632ea3ed8d..0b1ec8fd85ae5 100644 --- a/server/src/test/java/org/opensearch/indices/ShardLimitValidatorTests.java +++ b/server/src/test/java/org/opensearch/indices/ShardLimitValidatorTests.java @@ -214,6 +214,25 @@ public void testNonSystemIndexCreationFailsWithMaxShardLimitOnCluster() { ); } + public void testComputedMaxShardsOfClusterIntOverFlow() { + final int maxShardLimitPerNode = 500_000_000; + ClusterState state = createClusterForShardLimitTest(15, 1, 1); + Optional errorMessage = ShardLimitValidator.checkShardLimit(2, state, maxShardLimitPerNode, -1); + assertFalse(errorMessage.isPresent()); + + errorMessage = ShardLimitValidator.checkShardLimit(Integer.MAX_VALUE - 1, state, maxShardLimitPerNode, -1); + assertEquals( + "this action would add [" + + (Integer.MAX_VALUE - 1) + + "] total shards, but this cluster currently has [" + + 2 + + "]/[" + + Integer.MAX_VALUE + + "] maximum shards open", + errorMessage.get() + ); + } + public void testNonSystemIndexCreationPassesWithMaxShardLimitOnCluster() { final int maxShardLimitOnCluster = 5; Settings limitOnlySettings = Settings.builder()