[PATCH 1/2] Check vinyl index options on box cfg and space alter

Vladimir Davydov vdavydov.dev at gmail.com
Sun Feb 18 19:05:56 MSK 2018


Currently, one can set insane values for most vinyl index options, which
will most certainly result in a crash (e.g. bloom_fpr = 100). Add some
sanity checks.
---
 src/box/alter.cc                        | 30 +++++++++++++++----
 src/box/box.cc                          | 52 +++++++++++++++++++++++++++------
 test/box-tap/cfg.test.lua               | 40 ++++++-------------------
 test/vinyl/ddl.result                   | 40 +++++++++++++++++++++++++
 test/vinyl/ddl.test.lua                 | 11 +++++++
 test/vinyl/write_iterator_rand.result   | 16 +++++-----
 test/vinyl/write_iterator_rand.test.lua | 16 +++++-----
 7 files changed, 144 insertions(+), 61 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index e66863cb..af9fbb52 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -236,13 +236,33 @@ index_opts_decode(struct index_opts *opts, const char *map)
 			  BOX_INDEX_FIELD_OPTS, "distance must be either "\
 			  "'euclid' or 'manhattan'");
 	}
-	if (opts->run_count_per_level <= 0)
+	if (opts->range_size <= 0) {
 		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
 			  BOX_INDEX_FIELD_OPTS,
-			  "run_count_per_level must be > 0");
-	if (opts->run_size_ratio <= 1)
-		tnt_raise(ClientError, ER_WRONG_SPACE_OPTIONS,
-			  BOX_INDEX_FIELD_OPTS, "run_size_ratio must be > 1");
+			  "range_size must be greater than 0");
+	}
+	if (opts->page_size <= 0 || opts->page_size > opts->range_size) {
+		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
+			  BOX_INDEX_FIELD_OPTS,
+			  "page_size must be greater than 0 and "
+			  "less than or equal to range_size");
+	}
+	if (opts->run_count_per_level <= 0) {
+		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
+			  BOX_INDEX_FIELD_OPTS,
+			  "run_count_per_level must be greater than 0");
+	}
+	if (opts->run_size_ratio <= 1) {
+		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
+			  BOX_INDEX_FIELD_OPTS,
+			  "run_size_ratio must be greater than 1");
+	}
+	if (opts->bloom_fpr <= 0 || opts->bloom_fpr > 1) {
+		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
+			  BOX_INDEX_FIELD_OPTS,
+			  "bloom_fpr must be greater than 0 and "
+			  "less than or equal to 1");
+	}
 }
 
 /**
diff --git a/src/box/box.cc b/src/box/box.cc
index f055788d..0ded9728 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -479,6 +479,48 @@ box_check_wal_max_size(int64_t wal_max_size)
 	return wal_max_size;
 }
 
+static void
+box_check_vinyl_options(void)
+{
+	int read_threads = cfg_geti("vinyl_read_threads");
+	int write_threads = cfg_geti("vinyl_write_threads");
+	int64_t range_size = cfg_geti64("vinyl_range_size");
+	int64_t page_size = cfg_geti64("vinyl_page_size");
+	int run_count_per_level = cfg_geti("vinyl_run_count_per_level");
+	double run_size_ratio = cfg_getd("vinyl_run_size_ratio");
+	double bloom_fpr = cfg_getd("vinyl_bloom_fpr");
+
+	if (read_threads < 1) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_read_threads",
+			  "must be greater than or equal to 1");
+	}
+	if (write_threads < 2) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_write_threads",
+			  "must be greater than or equal to 2");
+	}
+	if (range_size <= 0) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_range_size",
+			  "must be greater than 0");
+	}
+	if (page_size <= 0 || page_size > range_size) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_page_size",
+			  "must be greater than 0 and less than "
+			  "or equal to vinyl_range_size");
+	}
+	if (run_count_per_level <= 0) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_run_count_per_level",
+			  "must be greater than 0");
+	}
+	if (run_size_ratio <= 1) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_run_size_ratio",
+			  "must be greater than 1");
+	}
+	if (bloom_fpr <= 0 || bloom_fpr > 1) {
+		tnt_raise(ClientError, ER_CFG, "vinyl_bloom_fpr",
+			  "must be greater than 0 and less than or equal to 1");
+	}
+}
+
 void
 box_check_config()
 {
@@ -498,15 +540,7 @@ box_check_config()
 	box_check_wal_max_size(cfg_geti64("wal_max_size"));
 	box_check_wal_mode(cfg_gets("wal_mode"));
 	box_check_memtx_min_tuple_size(cfg_geti64("memtx_min_tuple_size"));
-	if (cfg_geti64("vinyl_page_size") > cfg_geti64("vinyl_range_size"))
-		tnt_raise(ClientError, ER_CFG, "vinyl_page_size",
-			  "can't be greater than vinyl_range_size");
-	if (cfg_geti("vinyl_read_threads") < 1)
-		tnt_raise(ClientError, ER_CFG,
-			  "vinyl_read_threads", "must be >= 1");
-	if (cfg_geti("vinyl_write_threads") < 2)
-		tnt_raise(ClientError, ER_CFG,
-			  "vinyl_write_threads", "must be >= 2");
+	box_check_vinyl_options();
 }
 
 /*
diff --git a/test/box-tap/cfg.test.lua b/test/box-tap/cfg.test.lua
index 67991ecf..949f2aaa 100755
--- a/test/box-tap/cfg.test.lua
+++ b/test/box-tap/cfg.test.lua
@@ -6,7 +6,7 @@ local socket = require('socket')
 local fio = require('fio')
 local uuid = require('uuid')
 local msgpack = require('msgpack')
-test:plan(80)
+test:plan(84)
 
 --------------------------------------------------------------------------------
 -- Invalid values
@@ -33,6 +33,14 @@ invalid('listen', '//!')
 invalid('log', ':')
 invalid('log', 'syslog:xxx=')
 invalid('log_level', 'unknown')
+invalid('vinyl_read_threads', 0)
+invalid('vinyl_write_threads', 1)
+invalid('vinyl_range_size', 0)
+invalid('vinyl_page_size', 0)
+invalid('vinyl_run_count_per_level', 0)
+invalid('vinyl_run_size_ratio', 1)
+invalid('vinyl_bloom_fpr', 0)
+invalid('vinyl_bloom_fpr', 1.1)
 
 test:is(type(box.cfg), 'function', 'box is not started')
 
@@ -259,36 +267,6 @@ os.exit(0)
 ]]
 test:is(run_script(code), 0, "page size equal with range")
 
---
--- there is at least one vinyl reader thread.
---
-code = [[
-box.cfg{vinyl_read_threads = 0}
-os.exit(0)
-]]
-test:is(run_script(code), PANIC, "vinyl_read_threads = 0")
-
-code = [[
-box.cfg{vinyl_read_threads = 1}
-os.exit(0)
-]]
-test:is(run_script(code), 0, "vinyl_read_threads = 1")
-
---
--- gh-2150 one vinyl worker thread is reserved for dumps
---
-code = [[
-box.cfg{vinyl_write_threads = 1}
-os.exit(0)
-]]
-test:is(run_script(code), PANIC, "vinyl_write_threads = 1")
-
-code = [[
-box.cfg{vinyl_write_threads = 2}
-os.exit(0)
-]]
-test:is(run_script(code), 0, "vinyl_write_threads = 2")
-
 -- test memtx options upgrade
 code = [[
 box.cfg{slab_alloc_arena = 0.2, slab_alloc_minimal = 16,
diff --git a/test/vinyl/ddl.result b/test/vinyl/ddl.result
index 45a38344..5b5e8517 100644
--- a/test/vinyl/ddl.result
+++ b/test/vinyl/ddl.result
@@ -4,6 +4,46 @@ fiber = require('fiber')
 test_run = require('test_run').new()
 ---
 ...
+-- sanity checks
+space = box.schema.space.create('test', {engine = 'vinyl' })
+---
+...
+space:create_index('pk', {range_size = 0})
+---
+- error: 'Wrong index options (field 4): range_size must be greater than 0'
+...
+space:create_index('pk', {page_size = 0})
+---
+- error: 'Wrong index options (field 4): page_size must be greater than 0 and less
+    than or equal to range_size'
+...
+space:create_index('pk', {page_size = 8192, range_size = 4096})
+---
+- error: 'Wrong index options (field 4): page_size must be greater than 0 and less
+    than or equal to range_size'
+...
+space:create_index('pk', {run_count_per_level = 0})
+---
+- error: 'Wrong index options (field 4): run_count_per_level must be greater than
+    0'
+...
+space:create_index('pk', {run_size_ratio = 1})
+---
+- error: 'Wrong index options (field 4): run_size_ratio must be greater than 1'
+...
+space:create_index('pk', {bloom_fpr = 0})
+---
+- error: 'Wrong index options (field 4): bloom_fpr must be greater than 0 and less
+    than or equal to 1'
+...
+space:create_index('pk', {bloom_fpr = 1.1})
+---
+- error: 'Wrong index options (field 4): bloom_fpr must be greater than 0 and less
+    than or equal to 1'
+...
+space:drop()
+---
+...
 -- space secondary index create
 space = box.schema.space.create('test', { engine = 'vinyl' })
 ---
diff --git a/test/vinyl/ddl.test.lua b/test/vinyl/ddl.test.lua
index 53205df9..4fdfd9ad 100644
--- a/test/vinyl/ddl.test.lua
+++ b/test/vinyl/ddl.test.lua
@@ -1,6 +1,17 @@
 fiber = require('fiber')
 test_run = require('test_run').new()
 
+-- sanity checks
+space = box.schema.space.create('test', {engine = 'vinyl' })
+space:create_index('pk', {range_size = 0})
+space:create_index('pk', {page_size = 0})
+space:create_index('pk', {page_size = 8192, range_size = 4096})
+space:create_index('pk', {run_count_per_level = 0})
+space:create_index('pk', {run_size_ratio = 1})
+space:create_index('pk', {bloom_fpr = 0})
+space:create_index('pk', {bloom_fpr = 1.1})
+space:drop()
+
 -- space secondary index create
 space = box.schema.space.create('test', { engine = 'vinyl' })
 index1 = space:create_index('primary')
diff --git a/test/vinyl/write_iterator_rand.result b/test/vinyl/write_iterator_rand.result
index c45df7bd..e1affa7a 100644
--- a/test/vinyl/write_iterator_rand.result
+++ b/test/vinyl/write_iterator_rand.result
@@ -198,40 +198,40 @@ test_run:cmd("setopt delimiter ''");
 - true
 ...
 -- Tests on write iterator with random combinations of page_size and range_size
-range_size = math.random(128, 256)
+page_size = math.random(128, 256)
 ---
 ...
-page_size = range_size * math.random(10, 20)
+range_size = page_size * math.random(10, 20)
 ---
 ...
 fill_space_with_sizes(page_size, range_size, 300)
 ---
 - ok
 ...
-range_size = math.random(256, 512)
+page_size = math.random(256, 512)
 ---
 ...
-page_size = range_size * math.random(10, 20)
+range_size = page_size * math.random(10, 20)
 ---
 ...
 fill_space_with_sizes(page_size, range_size, 500)
 ---
 - ok
 ...
-range_size = math.random(512, 1024)
+page_size = math.random(512, 1024)
 ---
 ...
-page_size = range_size * math.random(10, 20)
+range_size = page_size * math.random(10, 20)
 ---
 ...
 fill_space_with_sizes(page_size, range_size, 700)
 ---
 - ok
 ...
-range_size = math.random(1024, 2048)
+page_size = math.random(1024, 2048)
 ---
 ...
-page_size = range_size * math.random(10, 20)
+range_size = page_size * math.random(10, 20)
 ---
 ...
 fill_space_with_sizes(page_size, range_size, 900)
diff --git a/test/vinyl/write_iterator_rand.test.lua b/test/vinyl/write_iterator_rand.test.lua
index ae2abec3..345b1d99 100644
--- a/test/vinyl/write_iterator_rand.test.lua
+++ b/test/vinyl/write_iterator_rand.test.lua
@@ -187,18 +187,18 @@ test_run:cmd("setopt delimiter ''");
 
 -- Tests on write iterator with random combinations of page_size and range_size
 
-range_size = math.random(128, 256)
-page_size = range_size * math.random(10, 20)
+page_size = math.random(128, 256)
+range_size = page_size * math.random(10, 20)
 fill_space_with_sizes(page_size, range_size, 300)
 
-range_size = math.random(256, 512)
-page_size = range_size * math.random(10, 20)
+page_size = math.random(256, 512)
+range_size = page_size * math.random(10, 20)
 fill_space_with_sizes(page_size, range_size, 500)
 
-range_size = math.random(512, 1024)
-page_size = range_size * math.random(10, 20)
+page_size = math.random(512, 1024)
+range_size = page_size * math.random(10, 20)
 fill_space_with_sizes(page_size, range_size, 700)
 
-range_size = math.random(1024, 2048)
-page_size = range_size * math.random(10, 20)
+page_size = math.random(1024, 2048)
+range_size = page_size * math.random(10, 20)
 fill_space_with_sizes(page_size, range_size, 900)
-- 
2.11.0




More information about the Tarantool-patches mailing list