summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2012-11-26 11:20:13 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2012-11-26 12:16:47 +0100
commit1ef98310187a7b287255cacd4b56160e48100d03 (patch)
treee815161b4cc1299ab4e9f0d1826cb894ed8f7678
parent953080e4fc271ad200736f3584f41e24dfe063ca (diff)
downloadlvm2-1ef98310187a7b287255cacd4b56160e48100d03.tar.gz
thin: support configurable thin pool defaults
Configurable settings for thin pool create if they are not specified on command line. New supported lvm.conf options are: allocation/thin_pool_chunk_size allocation/thin_pool_discards allocation/thin_pool_zero
-rw-r--r--WHATS_NEW1
-rw-r--r--doc/example.conf.in17
-rw-r--r--lib/config/defaults.h3
-rw-r--r--lib/thin/thin.c11
-rw-r--r--tools/toollib.c48
5 files changed, 64 insertions, 16 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 068f453a4..85fcd3e9f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.99 -
===================================
+ Add lvm.conf thin pool defs thin_pool_{chunk_size|discards|zero}.
Support discards for non-power-of-2 thin pool chunks.
Automatically restore MISSING PVs with no MDAs.
When no '-i' argument is given for RAID10, default to 2 stripes.
diff --git a/doc/example.conf.in b/doc/example.conf.in
index 7f94223ea..1a3ee1b69 100644
--- a/doc/example.conf.in
+++ b/doc/example.conf.in
@@ -232,6 +232,23 @@ allocation {
# Set to 1 to guarantee that thin pool metadata will always
# be placed on different PVs from the pool data.
thin_pool_metadata_require_separate_pvs = 0
+
+ # Specify the minimal chunk size (in KB) for thin pool volumes.
+ # Use of the larger chunk size may improve perfomance for plain
+ # thin volumes, however using them for snapshot volumes is less efficient,
+ # as it consumes more space and takes extra time for copying.
+ # When unset, lvm tries to estimate chunk size starting from 64KB
+ # Supported values are in range from 64 to 1048576.
+ # thin_pool_chunk_size = 64
+
+ # Specify discards behavior of the thin pool volume.
+ # Select one of "ignore", "nopassdown", "passdown"
+ # thin_pool_discards = "passdown"
+
+ # Set to 0, to disable zeroing of thin pool data chunks before their
+ # first use.
+ # N.B. zeroing larger thin pool chunk size degrades performance.
+ # thin_pool_zero = 1
}
# This section that allows you to configure the nature of the
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 9730a2d78..348fa7533 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -69,6 +69,9 @@
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */
+#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */
+#define DEFAULT_THIN_POOL_DISCARDS "passdown"
+#define DEFAULT_THIN_POOL_ZERO 1
#define DEFAULT_UMASK 0077
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 693b8b694..f6ac437e0 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -282,10 +282,15 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
return_0;
if (attr & THIN_FEATURE_DISCARDS) {
+ /* Use ignore for discards ignore or non-power-of-2 chunk_size and <1.5 target */
/* FIXME: Check whether underlying dev supports discards */
- if (!dm_tree_node_set_thin_pool_discard(node,
- seg->discards == THIN_DISCARDS_IGNORE,
- seg->discards == THIN_DISCARDS_NO_PASSDOWN))
+ if (((!(attr & THIN_FEATURE_DISCARDS_NON_POWER_2) &&
+ (seg->chunk_size & (seg->chunk_size - 1))) ||
+ (seg->discards == THIN_DISCARDS_IGNORE)) &&
+ !dm_tree_node_set_thin_pool_discard(node, 1, 0))
+ return_0;
+ else if (!dm_tree_node_set_thin_pool_discard(node, 0,
+ (seg->discards == THIN_DISCARDS_NO_PASSDOWN)))
return_0;
} else if (seg->discards != THIN_DISCARDS_IGNORE)
log_warn_suppress(_no_discards++, "WARNING: Thin pool target does "
diff --git a/tools/toollib.c b/tools/toollib.c
index ba1ba94b5..4c9a43d05 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1528,20 +1528,41 @@ int get_pool_params(struct cmd_context *cmd,
uint64_t *pool_metadata_size,
int *zero)
{
- if (arg_count(cmd, zero_ARG))
- *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
- else
- *zero = 1; /* TODO: Make default configurable */
-
- *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG,
- THIN_DISCARDS_PASSDOWN);
+ const char *dstr;
- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
- log_error("Negative chunk size is invalid.");
- return 0;
+ if (arg_count(cmd, zero_ARG)) {
+ *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
+ log_very_verbose("Setting pool zeroing: %u", *zero);
+ } else
+ *zero = find_config_tree_int(cmd,
+ "allocation/thin_pool_zero",
+ DEFAULT_THIN_POOL_ZERO);
+
+ if (arg_count(cmd, discards_ARG)) {
+ *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0);
+ log_very_verbose("Setting pool discards: %s",
+ get_pool_discards_name(*discards));
+ } else {
+ dstr = find_config_tree_str(cmd,
+ "allocation/thin_pool_discards",
+ DEFAULT_THIN_POOL_DISCARDS);
+ if (!get_pool_discards(dstr, discards))
+ return_0;
}
- *chunk_size = arg_uint_value(cmd, chunksize_ARG,
- DM_THIN_MIN_DATA_BLOCK_SIZE);
+
+ if (arg_count(cmd, chunksize_ARG)) {
+ if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) {
+ log_error("Negative chunk size is invalid.");
+ return 0;
+ }
+ *chunk_size = arg_uint_value(cmd, chunksize_ARG,
+ DM_THIN_MIN_DATA_BLOCK_SIZE);
+ log_very_verbose("Setting pool chunk size: %s",
+ display_size(cmd, *chunk_size));
+ } else
+ *chunk_size = find_config_tree_int(cmd,
+ "allocation/thin_pool_chunk_size",
+ DEFAULT_THIN_POOL_CHUNK_SIZE) * 2;
if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
(*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) {
@@ -1619,7 +1640,8 @@ int update_pool_params(struct cmd_context *cmd, unsigned attr,
else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)
*chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
- log_verbose("Setting chunk size %uKiB.", *chunk_size / 2);
+ log_verbose("Setting chunk size %s.",
+ display_size(cmd, *chunk_size));
} else if (*chunk_size < estimate_chunk_size) {
/* Suggest bigger chunk size */
log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.",