[lvm-devel] master - cache: new API for libdm
Zdenek Kabelac
zkabelac at fedoraproject.org
Mon Nov 10 21:06:29 UTC 2014
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3e230a8ad80c0c2f48c04979405fe2897f7ef769
Commit: 3e230a8ad80c0c2f48c04979405fe2897f7ef769
Parent: 824019531cbba02c722cb0bf0957ac84eccef3b9
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Sun Nov 9 20:18:00 2014 +0100
Committer: Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Mon Nov 10 22:05:49 2014 +0100
cache: new API for libdm
---
lib/cache_segtype/cache.c | 130 +++++++++++--------------------------
lib/metadata/cache_manip.c | 14 +---
lib/metadata/metadata-exported.h | 13 ++---
tools/lvconvert.c | 2 +-
4 files changed, 48 insertions(+), 111 deletions(-)
diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c
index ea480de..6dcbf42 100644
--- a/lib/cache_segtype/cache.c
+++ b/lib/cache_segtype/cache.c
@@ -38,8 +38,7 @@ static int _cache_pool_text_import(struct lv_segment *seg,
uint32_t chunk_size;
struct logical_volume *data_lv, *meta_lv;
const char *str = NULL;
- char *argv_str;
- struct dm_pool *mem = seg->lv->vg->vgmem; //FIXME: what mempool should be used?
+ struct dm_pool *mem = seg->lv->vg->vgmem;
if (!dm_config_has_node(sn, "data"))
return SEG_LOG_ERROR("Cache data not specified in");
@@ -62,7 +61,7 @@ static int _cache_pool_text_import(struct lv_segment *seg,
/*
* Read in features:
- * cache_mode = {writethrough|writeback}
+ * cache_mode = {passthrough|writethrough|writeback}
*
* 'cache_mode' does not have to be present.
*/
@@ -74,76 +73,30 @@ static int _cache_pool_text_import(struct lv_segment *seg,
}
/*
- * Read in core arguments (these are key/value pairs)
- * core_argc = <# args>
- * core_argv = "[<key> <value>]..."
+ * Read in policy args:
+ * mq {
+ * migration_threshold=2048
+ * sequention_threashold=100
+ * random_threashold=200
+ * read_promote_adjustment=10
+ * write_promote_adjustment=20
+ * discard_promote_adjustment=40
*
- * 'core_argc' does not have to be present. If it is not present,
- * any other core_* fields are ignored. If it is present, then
- * 'core_argv' must be present - even if they are
- * 'core_argc = 0' and 'core_argv = ""'.
- */
- if (dm_config_has_node(sn, "core_argc")) {
- if (!dm_config_has_node(sn, "core_argv"))
- return SEG_LOG_ERROR("not all core arguments defined in");
-
- if (!dm_config_get_uint32(sn, "core_argc", &seg->core_argc))
- return SEG_LOG_ERROR("Unable to read core_argc in");
-
- str = dm_config_find_str(sn, "core_argv", NULL);
- if ((str && !seg->core_argc) || (!str && seg->core_argc))
- return SEG_LOG_ERROR("core_argc and core_argv do"
- " not match in");
-
- if (!(seg->core_argv =
- dm_pool_alloc(mem, sizeof(char *) * seg->core_argc)))
- return_0;
- if (str &&
- (!(argv_str = dm_pool_strdup(mem, str)) ||
- ((int)seg->core_argc != dm_split_words(argv_str, seg->core_argc,
- 0, (char **) seg->core_argv))))
- return SEG_LOG_ERROR("core_argc and core_argv do"
- " not match in");
- }
-
- /*
- * Read in policy:
- * policy_name = "<policy_name>"
- * policy_argc = <# args>
- * policy_argv = "[<key> <value>]..."
+ * <key> = <value>
+ * <key> = <value>
+ * ...
+ * }
*
- * 'policy_name' does not have to be present. If it is not present,
- * any other policy_* fields are ignored. If it is present, then
- * the other policy_* fields must be present - even if they are
- * 'policy_argc = 0' and 'policy_argv = ""'.
+ * If the policy is not present, default policy is used.
*/
- if (dm_config_has_node(sn, "policy_name")) {
- if (!dm_config_has_node(sn, "policy_argc") ||
- !dm_config_has_node(sn, "policy_argv"))
- return SEG_LOG_ERROR("not all policy arguments defined in");
- if (!(str = dm_config_find_str(sn, "policy_name", NULL)))
- return SEG_LOG_ERROR("policy_name must be a string in");
- seg->policy_name = dm_pool_strdup(mem, str);
-
- if (!dm_config_get_uint32(sn, "policy_argc", &seg->policy_argc))
- return SEG_LOG_ERROR("Unable to read policy_argc in");
-
- str = dm_config_find_str(sn, "policy_argv", NULL);
- if ((str && !seg->policy_argc) || (!str && seg->policy_argc))
- return SEG_LOG_ERROR("policy_argc and policy_argv do"
- " not match in");
-
- if (!(seg->policy_argv =
- dm_pool_alloc(mem, sizeof(char *) * seg->policy_argc)))
- return_0;
- if (str &&
- (!(argv_str = dm_pool_strdup(mem, str)) ||
- ((int)seg->policy_argc != dm_split_words(argv_str,
- seg->policy_argc,
- 0, (char **) seg->policy_argv))))
- return SEG_LOG_ERROR("policy_argc and policy_argv do"
- " not match in");
- }
+ for (; sn; sn = sn->sib)
+ if (!sn->v) {
+ if (seg->policy_args)
+ return SEG_LOG_ERROR("only a singly policy is supported for");
+
+ if (!(seg->policy_args = dm_config_clone_node_with_mem(mem, sn, 0)))
+ return_0;
+ }
if (!attach_pool_data_lv(seg, data_lv))
return_0;
@@ -165,8 +118,6 @@ static int _cache_pool_text_import_area_count(const struct dm_config_node *sn,
static int _cache_pool_text_export(const struct lv_segment *seg,
struct formatter *f)
{
- unsigned i;
- char buf[256]; //FIXME: IS THERE AN 'outf' THAT DOESN'T DO NEWLINE?!?
const char *cache_mode;
if (!(cache_mode = get_cache_pool_cachemode_name(seg)))
@@ -177,22 +128,8 @@ static int _cache_pool_text_export(const struct lv_segment *seg,
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
outf(f, "cache_mode = \"%s\"", cache_mode);
- if (seg->core_argc) {
- outf(f, "core_argc = %u", seg->core_argc);
- outf(f, "core_argv = \"");
- for (i = 0; i < seg->core_argc; i++)
- outf(f, "%s%s", i ? " " : "", seg->core_argv[i]);
- outf(f, "\"");
- }
-
- if (seg->policy_name) {
- outf(f, "policy_name = \"%s\"", seg->policy_name);
- outf(f, "policy_argc = %u", seg->policy_argc);
- buf[0] = '\0';
- for (i = 0; i < seg->policy_argc; i++)
- sprintf(buf, "%s%s", i ? " " : "", seg->policy_argv[i]);
- outf(f, "policy_argv = \"%s\"", buf);
- }
+ if (seg->policy_args)
+ out_config_node(f, seg->policy_args);
return 1;
}
@@ -284,6 +221,12 @@ static int _cache_text_import(struct lv_segment *seg,
if (!set_lv_segment_area_lv(seg, 0, origin_lv, 0, 0))
return_0;
+
+ seg->cleaner_policy = 0;
+ if (dm_config_has_node(sn, "cleaner") &&
+ !dm_config_get_uint32(sn, "cleaner", &seg->cleaner_policy))
+ return SEG_LOG_ERROR("Could not read cache cleaner in");
+
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
return_0;
@@ -306,6 +249,9 @@ static int _cache_text_export(const struct lv_segment *seg, struct formatter *f)
outf(f, "cache_pool = \"%s\"", seg->pool_lv->name);
outf(f, "origin = \"%s\"", seg_lv(seg, 0)->name);
+ if (seg->cleaner_policy)
+ outf(f, "cleaner = 1");
+
return 1;
}
@@ -321,6 +267,8 @@ static int _cache_add_target_line(struct dev_manager *dm,
{
struct lv_segment *cache_pool_seg = first_seg(seg->pool_lv);
char *metadata_uuid, *data_uuid, *origin_uuid;
+ const char *policy_name = seg->cleaner_policy ? "cleaner" :
+ cache_pool_seg->policy_args ? cache_pool_seg->policy_args->key : NULL;
if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
return_0;
@@ -336,12 +284,12 @@ static int _cache_add_target_line(struct dev_manager *dm,
metadata_uuid,
data_uuid,
origin_uuid,
- NULL,
- cache_pool_seg->policy_name,
+ seg->cleaner_policy ? NULL : cache_pool_seg->policy_args,
+ policy_name,
cache_pool_seg->chunk_size))
return_0;
- return add_areas_line(dm, seg, node, 0u, seg->area_count);
+ return 1;
}
#endif /* DEVMAPPER_SUPPORT */
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 69a51ef..cce2911 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -301,19 +301,11 @@ int lv_cache_remove(struct logical_volume *cache_lv)
dm_pool_destroy(status->mem);
if (!is_cleaner) {
- /* We must swap in the cleaner to flush the cache */
+ /* Switch to cleaner policy to flush the cache */
log_print_unless_silent("Flushing cache for %s.", cache_lv->name);
-
- /*
- * Is there are clean way to free the memory for the name
- * and argv when changing the policy?
- */
- cache_seg->policy_name = "cleaner";
- cache_seg->policy_argc = 0;
- cache_seg->policy_argv = NULL;
-
+ cache_seg->cleaner_policy = 1;
/* update the kernel to put the cleaner policy in place */
- if (!lv_update_and_reload(cache_lv))
+ if (!lv_update_and_reload_origin(cache_lv))
return_0;
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 4c15fee..5acc511 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -425,15 +425,12 @@ struct lv_segment {
thin_discards_t discards; /* For thin_pool */
struct dm_list thin_messages; /* For thin_pool */
struct logical_volume *external_lv; /* For thin */
- struct logical_volume *pool_lv; /* For thin */
+ struct logical_volume *pool_lv; /* For thin, cache */
uint32_t device_id; /* For thin, 24bit */
- uint32_t feature_flags; /* For cache */
- unsigned core_argc; /* For cache */
- const char **core_argv; /* For cache */
- const char *policy_name; /* For cache */
- unsigned policy_argc; /* For cache */
- const char **policy_argv; /* For cache */
+ uint64_t feature_flags; /* For cache_pool */
+ struct dm_config_node *policy_args; /* For cache_pool (-> policy_name) */
+ unsigned cleaner_policy; /* For cache */
struct logical_volume *replicator;/* For replicator-devs - link to replicator LV */
struct logical_volume *rlog_lv; /* For replicators */
@@ -851,7 +848,7 @@ struct lvcreate_params {
uint32_t min_recovery_rate; /* RAID */
uint32_t max_recovery_rate; /* RAID */
- uint32_t feature_flags; /* cache */
+ uint64_t feature_flags; /* cache */
const struct segment_type *segtype; /* all */
unsigned target_attr; /* all */
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 8b09ee6..d4f3db1 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -48,7 +48,7 @@ struct lvconvert_params {
uint32_t stripes;
uint32_t stripe_size;
uint32_t read_ahead;
- uint32_t feature_flags; /* cache_pool */
+ uint64_t feature_flags; /* cache_pool */
const struct segment_type *segtype;
unsigned target_attr;
More information about the lvm-devel
mailing list