Skip to content

Commit 153b93f

Browse files
committed
Snapshot/Restore: better handle incorrect chunk_size settings in FS repo (#26844)
Specifying a negative value or null as a chunk_size in FS repository can lead to corrupt snapshots. Closes #26843
1 parent 54085b0 commit 153b93f

File tree

4 files changed

+32
-23
lines changed

4 files changed

+32
-23
lines changed

core/src/main/java/org/elasticsearch/index/snapshots/blobstore/BlobStoreIndexShardSnapshot.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public FileInfo(String name, StoreFileMetaData metaData, ByteSizeValue partSize)
6565
this.metadata = metaData;
6666

6767
long partBytes = Long.MAX_VALUE;
68-
if (partSize != null) {
68+
if (partSize != null && partSize.getBytes() > 0) {
6969
partBytes = partSize.getBytes();
7070
}
7171

core/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ protected BlobStoreRepository(RepositoryMetaData metadata, Settings globalSettin
259259
BlobStoreIndexShardSnapshot::fromXContent, namedXContentRegistry);
260260
indexShardSnapshotsFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_INDEX_CODEC, SNAPSHOT_INDEX_NAME_FORMAT,
261261
BlobStoreIndexShardSnapshots::fromXContent, namedXContentRegistry, isCompress());
262+
ByteSizeValue chunkSize = chunkSize();
263+
if (chunkSize != null && chunkSize.getBytes() <= 0) {
264+
throw new IllegalArgumentException("the chunk size cannot be negative: [" + chunkSize + "]");
265+
}
262266
}
263267

264268
@Override

core/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ public class FsRepository extends BlobStoreRepository {
5454
new Setting<>("location", "", Function.identity(), Property.NodeScope);
5555
public static final Setting<String> REPOSITORIES_LOCATION_SETTING =
5656
new Setting<>("repositories.fs.location", LOCATION_SETTING, Function.identity(), Property.NodeScope);
57-
public static final Setting<ByteSizeValue> CHUNK_SIZE_SETTING =
58-
Setting.byteSizeSetting("chunk_size", new ByteSizeValue(-1), Property.NodeScope);
59-
public static final Setting<ByteSizeValue> REPOSITORIES_CHUNK_SIZE_SETTING =
60-
Setting.byteSizeSetting("repositories.fs.chunk_size", new ByteSizeValue(-1), Property.NodeScope);
57+
public static final Setting<ByteSizeValue> CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size",
58+
new ByteSizeValue(Long.MAX_VALUE), new ByteSizeValue(5), new ByteSizeValue(Long.MAX_VALUE), Property.NodeScope);
59+
public static final Setting<ByteSizeValue> REPOSITORIES_CHUNK_SIZE_SETTING = Setting.byteSizeSetting("repositories.fs.chunk_size",
60+
new ByteSizeValue(Long.MAX_VALUE), new ByteSizeValue(5), new ByteSizeValue(Long.MAX_VALUE), Property.NodeScope);
6161
public static final Setting<Boolean> COMPRESS_SETTING = Setting.boolSetting("compress", false, Property.NodeScope);
6262
public static final Setting<Boolean> REPOSITORIES_COMPRESS_SETTING =
6363
Setting.boolSetting("repositories.fs.compress", false, Property.NodeScope);
@@ -95,10 +95,8 @@ public FsRepository(RepositoryMetaData metadata, Environment environment,
9595
blobStore = new FsBlobStore(settings, locationFile);
9696
if (CHUNK_SIZE_SETTING.exists(metadata.settings())) {
9797
this.chunkSize = CHUNK_SIZE_SETTING.get(metadata.settings());
98-
} else if (REPOSITORIES_CHUNK_SIZE_SETTING.exists(settings)) {
99-
this.chunkSize = REPOSITORIES_CHUNK_SIZE_SETTING.get(settings);
10098
} else {
101-
this.chunkSize = null;
99+
this.chunkSize = REPOSITORIES_CHUNK_SIZE_SETTING.get(settings);
102100
}
103101
this.compress = COMPRESS_SETTING.exists(metadata.settings()) ? COMPRESS_SETTING.get(metadata.settings()) : REPOSITORIES_COMPRESS_SETTING.get(settings);
104102
this.basePath = BlobPath.cleanPath();

core/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
106106
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
107107
import static org.elasticsearch.index.IndexSettings.INDEX_REFRESH_INTERVAL_SETTING;
108+
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
108109
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
109110
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
110111
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAliasesExist;
@@ -135,15 +136,29 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
135136
MockRepository.Plugin.class);
136137
}
137138

139+
private Settings randomRepoSettings() {
140+
Settings.Builder repoSettings = Settings.builder();
141+
repoSettings.put("location", randomRepoPath());
142+
if (randomBoolean()) {
143+
repoSettings.put("compress", randomBoolean());
144+
}
145+
if (randomBoolean()) {
146+
repoSettings.put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES);
147+
} else {
148+
if (randomBoolean()) {
149+
repoSettings.put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES);
150+
} else {
151+
repoSettings.put("chunk_size", (String) null);
152+
}
153+
}
154+
return repoSettings.build();
155+
}
156+
138157
public void testBasicWorkFlow() throws Exception {
139158
Client client = client();
140159

141160
logger.info("--> creating repository");
142-
assertAcked(client.admin().cluster().preparePutRepository("test-repo")
143-
.setType("fs").setSettings(Settings.builder()
144-
.put("location", randomRepoPath())
145-
.put("compress", randomBoolean())
146-
.put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES)));
161+
assertAcked(client.admin().cluster().preparePutRepository("test-repo").setType("fs").setSettings(randomRepoSettings()));
147162

148163
createIndex("test-idx-1", "test-idx-2", "test-idx-3");
149164
ensureGreen();
@@ -279,11 +294,7 @@ public void testFreshIndexUUID() {
279294
Client client = client();
280295

281296
logger.info("--> creating repository");
282-
assertAcked(client.admin().cluster().preparePutRepository("test-repo")
283-
.setType("fs").setSettings(Settings.builder()
284-
.put("location", randomRepoPath())
285-
.put("compress", randomBoolean())
286-
.put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES)));
297+
assertAcked(client.admin().cluster().preparePutRepository("test-repo").setType("fs").setSettings(randomRepoSettings()));
287298

288299
createIndex("test");
289300
String originalIndexUUID = client().admin().indices().prepareGetSettings("test").get().getSetting("test", IndexMetaData.SETTING_INDEX_UUID);
@@ -327,11 +338,7 @@ public void testRestoreWithDifferentMappingsAndSettings() throws Exception {
327338
Client client = client();
328339

329340
logger.info("--> creating repository");
330-
assertAcked(client.admin().cluster().preparePutRepository("test-repo")
331-
.setType("fs").setSettings(Settings.builder()
332-
.put("location", randomRepoPath())
333-
.put("compress", randomBoolean())
334-
.put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES)));
341+
assertAcked(client.admin().cluster().preparePutRepository("test-repo").setType("fs").setSettings(randomRepoSettings()));
335342

336343
logger.info("--> create index with foo type");
337344
assertAcked(prepareCreate("test-idx", 2, Settings.builder()

0 commit comments

Comments
 (0)