[lvm-devel] master - cache: Ability to convert an existing LV into a cached LV
Jonathan Brassow
jbrassow at fedoraproject.org
Wed Feb 12 15:55:39 UTC 2014
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0912cf67aae21446a10b3a22067aee1e8f792856
Commit: 0912cf67aae21446a10b3a22067aee1e8f792856
Parent: c8b6c4aee9a298a4c415d45c9e144d641bc7c6c6
Author: Jonathan Brassow <jbrassow at redhat.com>
AuthorDate: Wed Feb 12 09:55:35 2014 -0600
Committer: Jonathan Brassow <jbrassow at redhat.com>
CommitterDate: Wed Feb 12 09:55:35 2014 -0600
cache: Ability to convert an existing LV into a cached LV
Users now have the ability to convert their existing logical volumes
into cached logical volumes. A cache pool LV must be specified using
the '--cachepool' argument. The cachepool is the small, fast LV used
to cache the large, slow LV that is being converted.
---
lib/metadata/cache_manip.c | 7 +++++
tools/args.h | 1 +
tools/commands.h | 9 +++++-
tools/lvconvert.c | 54 ++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index f7518b0..673d90e 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -104,6 +104,13 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool,
return NULL;
}
+ if (!dm_list_empty(&pool->segs_using_this_lv)) {
+ seg = get_only_segment_using_this_lv(pool);
+ log_error("%s is already in use by %s",
+ pool->name, seg ? seg->lv->name : "another LV");
+ return NULL;
+ }
+
if (lv_is_cache_type(origin)) {
/*
* FIXME: We can layer caches, insert_layer_for_lv() would
diff --git a/tools/args.h b/tools/args.h
index 5f26511..f1a4ef4 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -63,6 +63,7 @@ arg(config_ARG, '\0', "config", string_arg, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0)
arg(cache_ARG, '\0', "cache", NULL, 0)
arg(cachemode_ARG, '\0', "cachemode", string_arg, 0)
+arg(cachepool_ARG, '\0', "cachepool", string_arg, 0)
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0)
arg(nameprefixes_ARG, '\0', "nameprefixes", NULL, 0)
arg(unquoted_ARG, '\0', "unquoted", NULL, 0)
diff --git a/tools/commands.h b/tools/commands.h
index a078b16..b0d608b 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -221,9 +221,14 @@ xx(lvconvert,
"\t[--poolmetadata CacheMetadataLogicalVolume[Path] |\n"
"\t [--poolmetadatasize size]\n"
"\t [--poolmetadataspare {y|n}]]\n"
- "\tCacheDataLogicalVolume[Path]\n\n",
+ "\tCacheDataLogicalVolume[Path]\n\n"
- alloc_ARG, background_ARG, cachemode_ARG, chunksize_ARG,
+ "lvconvert "
+ "--type cache\n"
+ "\t--cachepool CachePoolLogicalVolume[Path]\n"
+ "\tLogicalVolume[Path]\n\n",
+
+ alloc_ARG, background_ARG, cachemode_ARG, cachepool_ARG, chunksize_ARG,
corelog_ARG, discards_ARG, force_ARG, interval_ARG, merge_ARG, mirrorlog_ARG,
mirrors_ARG, name_ARG, noudevsync_ARG, originname_ARG, poolmetadata_ARG,
poolmetadatasize_ARG, poolmetadataspare_ARG, readahead_ARG, regionsize_ARG,
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 5774e11..d53b83a 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -28,6 +28,7 @@ struct lvconvert_params {
int zero;
const char *origin;
+ const char *cachepool;
const char *lv_name;
const char *lv_split_name;
const char *lv_name_full;
@@ -201,7 +202,7 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
/* FIXME: Check thin-pool and thin more thoroughly! */
if (!strcmp(type_str, "snapshot") ||
!strncmp(type_str, "raid", 4) ||
- !strcmp(type_str, "cache_pool") ||
+ !strcmp(type_str, "cache_pool") || !strcmp(type_str, "cache") ||
!strcmp(type_str, "thin-pool") || !strcmp(type_str, "thin"))
return 1;
@@ -288,7 +289,14 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
if (arg_count(cmd, thin_ARG))
lp->thin = 1;
- if (arg_count(cmd, thinpool_ARG) || cache_pool) {
+ if (arg_count(cmd, cachepool_ARG)) {
+ if (strcmp(type_str, "cache")) {
+ log_error("--cachepool argument is only valid with "
+ " the \"cache\" segment type");
+ return 0;
+ }
+ lp->cachepool = arg_str_value(cmd, cachepool_ARG, NULL);
+ } else if (arg_count(cmd, thinpool_ARG) || cache_pool) {
if (arg_count(cmd, merge_ARG)) {
log_error("--%spool and --merge are mutually exlusive.",
cache_pool ? "type cache_" : "thin");
@@ -2926,6 +2934,41 @@ out:
return r;
}
+static int _lvconvert_cache(struct logical_volume *origin,
+ struct lvconvert_params *lp)
+{
+ struct cmd_context *cmd = origin->vg->cmd;
+ struct logical_volume *cache_lv;
+ struct logical_volume *cachepool;
+
+ if (!lp->cachepool) {
+ log_error("--cachepool argument is required.");
+ return 0;
+ }
+
+ if (!(cachepool = find_lv(origin->vg, lp->cachepool))) {
+ log_error("Unable to find cache pool LV, %s", lp->cachepool);
+ return 0;
+ }
+
+ if (!(cache_lv = lv_cache_create(cachepool, origin)))
+ return_0;
+
+ if (!vg_write(cache_lv->vg))
+ return_0;
+ if (!suspend_lv(cmd, cache_lv))
+ return_0;
+ if (!vg_commit(cache_lv->vg))
+ return_0;
+ if (!resume_lv(cmd, cache_lv))
+ return_0;
+
+ log_print_unless_silent("%s/%s is now cached.",
+ cache_lv->vg->name, cache_lv->name);
+
+ return 1;
+}
+
static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
@@ -2996,6 +3039,13 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!_lvconvert_snapshot(cmd, lv, lp))
return_ECMD_FAILED;
+ } else if (segtype_is_cache(lp->segtype)) {
+ if (!archive(lv->vg))
+ return_ECMD_FAILED;
+
+ if (!_lvconvert_cache(lv, lp))
+ return_ECMD_FAILED;
+
} else if (segtype_is_cache_pool(lp->segtype)) {
if (!archive(lv->vg))
return_ECMD_FAILED;
More information about the lvm-devel
mailing list