mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Use "cachevol" to refer to cache on a single LV
and "cachepool" to refer to a cache on a cache pool object. The problem was that the --cachepool option was being used to refer to both a cache pool object, and to a standard LV used for caching. This could be somewhat confusing, and it made it less clear when each kind would be used. By separating them, it's clear when a cachepool or a cachevol should be used. Previously: - lvm would use the cache pool approach when the user passed a cache-pool LV to the --cachepool option. - lvm would use the cache vol approach when the user passed a standard LV in the --cachepool option. Now: - lvm will always use the cache pool approach when the user uses the --cachepool option. - lvm will always use the cache vol approach when the user uses the --cachevol option.
This commit is contained in:
parent
c8fc18e8bf
commit
a9eaab6beb
@ -833,7 +833,7 @@ static int _info(struct cmd_context *cmd,
|
|||||||
|
|
||||||
/* FIXME: could we just use dev_manager_info instead of this? */
|
/* FIXME: could we just use dev_manager_info instead of this? */
|
||||||
|
|
||||||
int get_cache_single_meta_data(struct cmd_context *cmd,
|
int get_cache_vol_meta_data(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct logical_volume *pool_lv,
|
struct logical_volume *pool_lv,
|
||||||
struct dm_info *info_meta, struct dm_info *info_data)
|
struct dm_info *info_meta, struct dm_info *info_data)
|
||||||
@ -876,7 +876,7 @@ int get_cache_single_meta_data(struct cmd_context *cmd,
|
|||||||
* devs?
|
* devs?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int remove_cache_single_meta_data(struct cmd_context *cmd,
|
int remove_cache_vol_meta_data(struct cmd_context *cmd,
|
||||||
struct dm_info *info_meta, struct dm_info *info_data)
|
struct dm_info *info_meta, struct dm_info *info_data)
|
||||||
{
|
{
|
||||||
struct dm_tree *dtree;
|
struct dm_tree *dtree;
|
||||||
@ -2375,7 +2375,7 @@ static int _pool_register_callback(struct dev_manager *dm,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Skip for single-device cache pool */
|
/* Skip for single-device cache pool */
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(first_seg(lv)->pool_lv))
|
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
|
if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
|
||||||
@ -2445,7 +2445,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
/* Unused cache pool is activated as metadata */
|
/* Unused cache pool is activated as metadata */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(first_seg(lv)->pool_lv) && dm->activation) {
|
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv) && dm->activation) {
|
||||||
struct logical_volume *pool_lv = first_seg(lv)->pool_lv;
|
struct logical_volume *pool_lv = first_seg(lv)->pool_lv;
|
||||||
struct lv_segment *lvseg = first_seg(lv);
|
struct lv_segment *lvseg = first_seg(lv);
|
||||||
struct dm_info info_meta;
|
struct dm_info info_meta;
|
||||||
@ -2637,7 +2637,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
if (seg->pool_lv &&
|
if (seg->pool_lv &&
|
||||||
(lv_is_cache_pool(seg->pool_lv) || lv_is_cache_single(seg->pool_lv) || dm->track_external_lv_deps) &&
|
(lv_is_cache_pool(seg->pool_lv) || lv_is_cache_vol(seg->pool_lv) || dm->track_external_lv_deps) &&
|
||||||
/* When activating and not origin_only detect linear 'overlay' over pool */
|
/* When activating and not origin_only detect linear 'overlay' over pool */
|
||||||
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, dm->activation ? origin_only : 1))
|
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, dm->activation ? origin_only : 1))
|
||||||
return_0;
|
return_0;
|
||||||
@ -3163,7 +3163,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(first_seg(lv)->pool_lv)) {
|
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv)) {
|
||||||
struct logical_volume *pool_lv = first_seg(lv)->pool_lv;
|
struct logical_volume *pool_lv = first_seg(lv)->pool_lv;
|
||||||
struct lv_segment *lvseg = first_seg(lv);
|
struct lv_segment *lvseg = first_seg(lv);
|
||||||
struct volume_group *vg = lv->vg;
|
struct volume_group *vg = lv->vg;
|
||||||
@ -3414,7 +3414,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
!_pool_register_callback(dm, dnode, lv))
|
!_pool_register_callback(dm, dnode, lv))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (lv_is_cache(lv) && !lv_is_cache_single(first_seg(lv)->pool_lv) &&
|
if (lv_is_cache(lv) && !lv_is_cache_vol(first_seg(lv)->pool_lv) &&
|
||||||
/* Register callback only for layer activation or non-layered cache LV */
|
/* Register callback only for layer activation or non-layered cache LV */
|
||||||
(layer || !lv_layer(lv)) &&
|
(layer || !lv_layer(lv)) &&
|
||||||
/* Register callback when metadata LV is NOT already active */
|
/* Register callback when metadata LV is NOT already active */
|
||||||
|
@ -107,12 +107,12 @@ int dev_manager_device_uses_vg(struct device *dev,
|
|||||||
|
|
||||||
int dev_manager_remove_dm_major_minor(uint32_t major, uint32_t minor);
|
int dev_manager_remove_dm_major_minor(uint32_t major, uint32_t minor);
|
||||||
|
|
||||||
int get_cache_single_meta_data(struct cmd_context *cmd,
|
int get_cache_vol_meta_data(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct logical_volume *pool_lv,
|
struct logical_volume *pool_lv,
|
||||||
struct dm_info *info_meta, struct dm_info *info_data);
|
struct dm_info *info_meta, struct dm_info *info_data);
|
||||||
|
|
||||||
int remove_cache_single_meta_data(struct cmd_context *cmd,
|
int remove_cache_vol_meta_data(struct cmd_context *cmd,
|
||||||
struct dm_info *info_meta, struct dm_info *info_data);
|
struct dm_info *info_meta, struct dm_info *info_data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,7 +49,7 @@ static void _cache_display(const struct lv_segment *seg)
|
|||||||
const struct dm_config_node *n;
|
const struct dm_config_node *n;
|
||||||
const struct lv_segment *setting_seg = NULL;
|
const struct lv_segment *setting_seg = NULL;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -540,7 +540,7 @@ static int _cache_text_import(struct lv_segment *seg,
|
|||||||
if (!id_read_format(&seg->data_id, uuid))
|
if (!id_read_format(&seg->data_id, uuid))
|
||||||
return SEG_LOG_ERROR("Couldn't format data_id in");
|
return SEG_LOG_ERROR("Couldn't format data_id in");
|
||||||
} else {
|
} else {
|
||||||
/* Do not call this when LV is cache_single. */
|
/* Do not call this when LV is cache_vol. */
|
||||||
/* load order is unknown, could be cache origin or pool LV, so check for both */
|
/* load order is unknown, could be cache origin or pool LV, so check for both */
|
||||||
if (!dm_list_empty(&pool_lv->segments))
|
if (!dm_list_empty(&pool_lv->segments))
|
||||||
_fix_missing_defaults(first_seg(pool_lv));
|
_fix_missing_defaults(first_seg(pool_lv));
|
||||||
@ -570,7 +570,7 @@ static int _cache_text_export(const struct lv_segment *seg, struct formatter *f)
|
|||||||
if (seg->cleaner_policy)
|
if (seg->cleaner_policy)
|
||||||
outf(f, "cleaner = 1");
|
outf(f, "cleaner = 1");
|
||||||
|
|
||||||
if (lv_is_cache_single(seg->pool_lv)) {
|
if (lv_is_cache_vol(seg->pool_lv)) {
|
||||||
outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
|
outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
|
||||||
|
|
||||||
if (!_settings_text_export(seg, f))
|
if (!_settings_text_export(seg, f))
|
||||||
@ -620,7 +620,7 @@ static int _cache_add_target_line(struct dev_manager *dm,
|
|||||||
|
|
||||||
cache_pool_seg = first_seg(seg->pool_lv);
|
cache_pool_seg = first_seg(seg->pool_lv);
|
||||||
|
|
||||||
if (lv_is_cache_single(seg->pool_lv))
|
if (lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
else
|
else
|
||||||
setting_seg = cache_pool_seg;
|
setting_seg = cache_pool_seg;
|
||||||
@ -668,7 +668,7 @@ static int _cache_add_target_line(struct dev_manager *dm,
|
|||||||
if (!(origin_uuid = build_dm_uuid(mem, seg_lv(seg, 0), NULL)))
|
if (!(origin_uuid = build_dm_uuid(mem, seg_lv(seg, 0), NULL)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!lv_is_cache_single(seg->pool_lv)) {
|
if (!lv_is_cache_vol(seg->pool_lv)) {
|
||||||
/* We don't use start/len when using separate data/meta devices. */
|
/* We don't use start/len when using separate data/meta devices. */
|
||||||
if (seg->metadata_len || seg->data_len) {
|
if (seg->metadata_len || seg->data_len) {
|
||||||
log_error(INTERNAL_ERROR "LV %s using unsupported ranges with cache pool.",
|
log_error(INTERNAL_ERROR "LV %s using unsupported ranges with cache pool.",
|
||||||
|
@ -72,7 +72,7 @@ static const struct flag _lv_flags[] = {
|
|||||||
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
|
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
|
||||||
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
|
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
|
||||||
{LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
|
{LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
|
||||||
{LV_CACHE_SINGLE, "CACHE_SINGLE", STATUS_FLAG},
|
{LV_CACHE_VOL, "CACHE_VOL", STATUS_FLAG},
|
||||||
{LV_NOSCAN, NULL, 0},
|
{LV_NOSCAN, NULL, 0},
|
||||||
{LV_TEMPORARY, NULL, 0},
|
{LV_TEMPORARY, NULL, 0},
|
||||||
{POOL_METADATA_SPARE, NULL, 0},
|
{POOL_METADATA_SPARE, NULL, 0},
|
||||||
|
@ -2780,7 +2780,7 @@ int lockd_lv_uses_lock(struct logical_volume *lv)
|
|||||||
if (lv_is_pool_metadata_spare(lv))
|
if (lv_is_pool_metadata_spare(lv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (lv_is_cache_single(lv))
|
if (lv_is_cache_vol(lv))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (lv_is_cache_pool(lv))
|
if (lv_is_cache_pool(lv))
|
||||||
|
@ -61,7 +61,7 @@ const char *display_cache_mode(const struct lv_segment *seg)
|
|||||||
{
|
{
|
||||||
const struct lv_segment *setting_seg = NULL;
|
const struct lv_segment *setting_seg = NULL;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -131,7 +131,7 @@ int cache_set_cache_mode(struct lv_segment *seg, cache_mode_t mode)
|
|||||||
if (seg_is_cache_pool(seg) && (mode == CACHE_MODE_UNSELECTED))
|
if (seg_is_cache_pool(seg) && (mode == CACHE_MODE_UNSELECTED))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -337,7 +337,7 @@ int validate_lv_cache_create_pool(const struct logical_volume *pool_lv)
|
|||||||
{
|
{
|
||||||
struct lv_segment *seg;
|
struct lv_segment *seg;
|
||||||
|
|
||||||
if (!lv_is_cache_pool(pool_lv) && !lv_is_cache_single(pool_lv)) {
|
if (!lv_is_cache_pool(pool_lv) && !lv_is_cache_vol(pool_lv)) {
|
||||||
log_error("Logical volume %s is not a cache pool.",
|
log_error("Logical volume %s is not a cache pool.",
|
||||||
display_lvname(pool_lv));
|
display_lvname(pool_lv));
|
||||||
return 0;
|
return 0;
|
||||||
@ -559,7 +559,7 @@ int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lv_detach_cache_single_while_active(struct cmd_context *cmd, struct logical_volume *cache_lv)
|
static int _lv_detach_cache_vol_while_active(struct cmd_context *cmd, struct logical_volume *cache_lv)
|
||||||
{
|
{
|
||||||
struct lv_segment *cache_seg = first_seg(cache_lv);
|
struct lv_segment *cache_seg = first_seg(cache_lv);
|
||||||
struct logical_volume *corigin_lv;
|
struct logical_volume *corigin_lv;
|
||||||
@ -582,7 +582,7 @@ static int _lv_detach_cache_single_while_active(struct cmd_context *cmd, struct
|
|||||||
/*
|
/*
|
||||||
* This info is needed to remove the cmeta/cdata devs at the end.
|
* This info is needed to remove the cmeta/cdata devs at the end.
|
||||||
*/
|
*/
|
||||||
if (!get_cache_single_meta_data(cmd, cache_lv, cache_pool_lv, &info_meta, &info_data)) {
|
if (!get_cache_vol_meta_data(cmd, cache_lv, cache_pool_lv, &info_meta, &info_data)) {
|
||||||
log_error("Failed to get info about cdata/cmeta for %s", display_lvname(cache_pool_lv));
|
log_error("Failed to get info about cdata/cmeta for %s", display_lvname(cache_pool_lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -604,7 +604,7 @@ static int _lv_detach_cache_single_while_active(struct cmd_context *cmd, struct
|
|||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_pool_lv->status &= ~LV_CACHE_SINGLE;
|
cache_pool_lv->status &= ~LV_CACHE_VOL;
|
||||||
|
|
||||||
if (!remove_layer_from_lv(cache_lv, corigin_lv)) {
|
if (!remove_layer_from_lv(cache_lv, corigin_lv)) {
|
||||||
log_error("Failed to remove cache layer from %s", display_lvname(cache_lv));
|
log_error("Failed to remove cache layer from %s", display_lvname(cache_lv));
|
||||||
@ -623,7 +623,7 @@ static int _lv_detach_cache_single_while_active(struct cmd_context *cmd, struct
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* These cmeta/cdata dm devs need to be removed since they are using cache_pool_lv. */
|
/* These cmeta/cdata dm devs need to be removed since they are using cache_pool_lv. */
|
||||||
if (!remove_cache_single_meta_data(cmd, &info_meta, &info_data))
|
if (!remove_cache_vol_meta_data(cmd, &info_meta, &info_data))
|
||||||
log_error("Failed to remove cdata/cmeta devs for %s", display_lvname(cache_pool_lv));
|
log_error("Failed to remove cdata/cmeta devs for %s", display_lvname(cache_pool_lv));
|
||||||
|
|
||||||
if (!deactivate_lv(cmd, cache_pool_lv))
|
if (!deactivate_lv(cmd, cache_pool_lv))
|
||||||
@ -652,7 +652,7 @@ static int _lv_detach_cache_single_while_active(struct cmd_context *cmd, struct
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lv_detach_cache_single_while_inactive(struct cmd_context *cmd, struct logical_volume *cache_lv)
|
static int _lv_detach_cache_vol_while_inactive(struct cmd_context *cmd, struct logical_volume *cache_lv)
|
||||||
{
|
{
|
||||||
struct lv_segment *cache_seg = first_seg(cache_lv);
|
struct lv_segment *cache_seg = first_seg(cache_lv);
|
||||||
struct logical_volume *corigin_lv;
|
struct logical_volume *corigin_lv;
|
||||||
@ -707,7 +707,7 @@ static int _lv_detach_cache_single_while_inactive(struct cmd_context *cmd, struc
|
|||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_pool_lv->status &= ~LV_CACHE_SINGLE;
|
cache_pool_lv->status &= ~LV_CACHE_VOL;
|
||||||
|
|
||||||
if (!remove_layer_from_lv(cache_lv, corigin_lv)) {
|
if (!remove_layer_from_lv(cache_lv, corigin_lv)) {
|
||||||
log_error("Failed to remove cache layer from %s", display_lvname(cache_lv));
|
log_error("Failed to remove cache layer from %s", display_lvname(cache_lv));
|
||||||
@ -724,7 +724,7 @@ static int _lv_detach_cache_single_while_inactive(struct cmd_context *cmd, struc
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_detach_cache_single(struct logical_volume *cache_lv)
|
int lv_detach_cache_vol(struct logical_volume *cache_lv)
|
||||||
{
|
{
|
||||||
struct cmd_context *cmd = cache_lv->vg->cmd;
|
struct cmd_context *cmd = cache_lv->vg->cmd;
|
||||||
|
|
||||||
@ -734,9 +734,9 @@ int lv_detach_cache_single(struct logical_volume *cache_lv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_active(cache_lv))
|
if (lv_is_active(cache_lv))
|
||||||
return _lv_detach_cache_single_while_active(cmd, cache_lv);
|
return _lv_detach_cache_vol_while_active(cmd, cache_lv);
|
||||||
else
|
else
|
||||||
return _lv_detach_cache_single_while_inactive(cmd, cache_lv);
|
return _lv_detach_cache_vol_while_inactive(cmd, cache_lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -763,7 +763,7 @@ int lv_cache_remove(struct logical_volume *cache_lv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_cache_single(cache_seg->pool_lv)) {
|
if (lv_is_cache_vol(cache_seg->pool_lv)) {
|
||||||
log_error(INTERNAL_ERROR "Incorrect remove for cache single");
|
log_error(INTERNAL_ERROR "Incorrect remove for cache single");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -952,7 +952,7 @@ int cache_set_policy(struct lv_segment *lvseg, const char *name,
|
|||||||
return 1; /* Policy and settings can be selected later when caching LV */
|
return 1; /* Policy and settings can be selected later when caching LV */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg_is_cache(lvseg) && lv_is_cache_single(lvseg->pool_lv))
|
if (seg_is_cache(lvseg) && lv_is_cache_vol(lvseg->pool_lv))
|
||||||
seg = lvseg;
|
seg = lvseg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(lvseg))
|
else if (seg_is_cache_pool(lvseg))
|
||||||
@ -1128,7 +1128,7 @@ int cache_set_metadata_format(struct lv_segment *seg, cache_metadata_format_t fo
|
|||||||
#define ONE_MB_S 2048 /* 1MB in sectors */
|
#define ONE_MB_S 2048 /* 1MB in sectors */
|
||||||
#define ONE_GB_S 2097152 /* 1GB in sectors */
|
#define ONE_GB_S 2097152 /* 1GB in sectors */
|
||||||
|
|
||||||
int cache_single_set_params(struct cmd_context *cmd,
|
int cache_vol_set_params(struct cmd_context *cmd,
|
||||||
struct logical_volume *cache_lv,
|
struct logical_volume *cache_lv,
|
||||||
struct logical_volume *pool_lv,
|
struct logical_volume *pool_lv,
|
||||||
uint64_t poolmetadatasize,
|
uint64_t poolmetadatasize,
|
||||||
@ -1428,7 +1428,7 @@ int wipe_cache_pool(struct logical_volume *cache_pool_lv)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* Only unused cache-pool could be activated and wiped */
|
/* Only unused cache-pool could be activated and wiped */
|
||||||
if ((!lv_is_cache_pool(cache_pool_lv) && !lv_is_cache_single(cache_pool_lv)) ||
|
if ((!lv_is_cache_pool(cache_pool_lv) && !lv_is_cache_vol(cache_pool_lv)) ||
|
||||||
!dm_list_empty(&cache_pool_lv->segs_using_this_lv)) {
|
!dm_list_empty(&cache_pool_lv->segs_using_this_lv)) {
|
||||||
log_error(INTERNAL_ERROR "Failed to wipe cache pool for volume %s.",
|
log_error(INTERNAL_ERROR "Failed to wipe cache pool for volume %s.",
|
||||||
display_lvname(cache_pool_lv));
|
display_lvname(cache_pool_lv));
|
||||||
|
@ -333,7 +333,7 @@ uint64_t lvseg_chunksize(const struct lv_segment *seg)
|
|||||||
|
|
||||||
if (lv_is_cow(seg->lv))
|
if (lv_is_cow(seg->lv))
|
||||||
size = (uint64_t) find_snapshot(seg->lv)->chunk_size;
|
size = (uint64_t) find_snapshot(seg->lv)->chunk_size;
|
||||||
else if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
else if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
size = (uint64_t) seg->chunk_size;
|
size = (uint64_t) seg->chunk_size;
|
||||||
else if (seg_is_pool(seg))
|
else if (seg_is_pool(seg))
|
||||||
size = (uint64_t) seg->chunk_size;
|
size = (uint64_t) seg->chunk_size;
|
||||||
@ -941,7 +941,7 @@ uint64_t lv_metadata_size(const struct logical_volume *lv)
|
|||||||
if (!(seg = first_seg(lv)))
|
if (!(seg = first_seg(lv)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
return seg->metadata_len;
|
return seg->metadata_len;
|
||||||
|
|
||||||
if (lv_is_thin_pool(lv) || lv_is_cache_pool(lv))
|
if (lv_is_thin_pool(lv) || lv_is_cache_pool(lv))
|
||||||
@ -1309,7 +1309,7 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
|
|||||||
|
|
||||||
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
|
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
|
||||||
repstr[6] = 't';
|
repstr[6] = 't';
|
||||||
else if (lv_is_cache_pool(lv) || lv_is_cache_single(lv) || lv_is_cache(lv) || lv_is_cache_origin(lv))
|
else if (lv_is_cache_pool(lv) || lv_is_cache_vol(lv) || lv_is_cache(lv) || lv_is_cache_origin(lv))
|
||||||
repstr[6] = 'C';
|
repstr[6] = 'C';
|
||||||
else if (lv_is_raid_type(lv))
|
else if (lv_is_raid_type(lv))
|
||||||
repstr[6] = 'r';
|
repstr[6] = 'r';
|
||||||
|
@ -422,7 +422,7 @@ static int _lv_layout_and_role_cache(struct dm_pool *mem,
|
|||||||
if (lv_is_cache(lv) &&
|
if (lv_is_cache(lv) &&
|
||||||
!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_CACHE]))
|
!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_CACHE]))
|
||||||
goto_bad;
|
goto_bad;
|
||||||
else if (lv_is_cache_pool(lv) || lv_is_cache_single(lv)) {
|
else if (lv_is_cache_pool(lv) || lv_is_cache_vol(lv)) {
|
||||||
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_CACHE]) ||
|
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_CACHE]) ||
|
||||||
!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_POOL]))
|
!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_POOL]))
|
||||||
goto_bad;
|
goto_bad;
|
||||||
@ -4453,7 +4453,7 @@ static int _rename_skip_pools_externals_cb(struct logical_volume *lv, void *data
|
|||||||
{
|
{
|
||||||
if (lv_is_pool(lv) ||
|
if (lv_is_pool(lv) ||
|
||||||
lv_is_vdo_pool(lv) ||
|
lv_is_vdo_pool(lv) ||
|
||||||
lv_is_cache_single(lv) ||
|
lv_is_cache_vol(lv) ||
|
||||||
lv_is_external_origin(lv))
|
lv_is_external_origin(lv))
|
||||||
return -1; /* and skip subLVs */
|
return -1; /* and skip subLVs */
|
||||||
|
|
||||||
@ -6225,8 +6225,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
if (!lockd_lv(cmd, lock_lv, "ex", LDLV_PERSISTENT))
|
if (!lockd_lv(cmd, lock_lv, "ex", LDLV_PERSISTENT))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(first_seg(lv)->pool_lv)) {
|
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv)) {
|
||||||
if (!lv_detach_cache_single(lv)) {
|
if (!lv_detach_cache_vol(lv)) {
|
||||||
log_error("Failed to detach cache from %s", display_lvname(lv));
|
log_error("Failed to detach cache from %s", display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -364,14 +364,14 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
|
|||||||
|
|
||||||
if (!seg->pool_lv) {
|
if (!seg->pool_lv) {
|
||||||
seg_error("is missing cache pool LV");
|
seg_error("is missing cache pool LV");
|
||||||
} else if (!lv_is_cache_pool(seg->pool_lv) && !lv_is_cache_single(seg->pool_lv))
|
} else if (!lv_is_cache_pool(seg->pool_lv) && !lv_is_cache_vol(seg->pool_lv))
|
||||||
seg_error("is not referencing cache pool LV");
|
seg_error("is not referencing cache pool LV");
|
||||||
} else { /* !cache */
|
} else { /* !cache */
|
||||||
if (seg->cleaner_policy)
|
if (seg->cleaner_policy)
|
||||||
seg_error("sets cleaner_policy");
|
seg_error("sets cleaner_policy");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_cache(lv) && seg->pool_lv && lv_is_cache_single(seg->pool_lv)) {
|
if (lv_is_cache(lv) && seg->pool_lv && lv_is_cache_vol(seg->pool_lv)) {
|
||||||
cache_setting_seg = seg;
|
cache_setting_seg = seg;
|
||||||
no_metadata_format = 1;
|
no_metadata_format = 1;
|
||||||
}
|
}
|
||||||
@ -805,7 +805,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
|
|||||||
if ((seg_count != 1) &&
|
if ((seg_count != 1) &&
|
||||||
(lv_is_cache(lv) ||
|
(lv_is_cache(lv) ||
|
||||||
lv_is_cache_pool(lv) ||
|
lv_is_cache_pool(lv) ||
|
||||||
lv_is_cache_single(lv) ||
|
lv_is_cache_vol(lv) ||
|
||||||
lv_is_raid(lv) ||
|
lv_is_raid(lv) ||
|
||||||
lv_is_snapshot(lv) ||
|
lv_is_snapshot(lv) ||
|
||||||
lv_is_thin_pool(lv) ||
|
lv_is_thin_pool(lv) ||
|
||||||
|
@ -152,7 +152,7 @@
|
|||||||
#define LV_VDO_POOL UINT64_C(0x0000000040000000) /* LV - Internal user only */
|
#define LV_VDO_POOL UINT64_C(0x0000000040000000) /* LV - Internal user only */
|
||||||
#define LV_VDO_POOL_DATA UINT64_C(0x8000000000000000) /* LV - Internal user only */
|
#define LV_VDO_POOL_DATA UINT64_C(0x8000000000000000) /* LV - Internal user only */
|
||||||
|
|
||||||
#define LV_CACHE_SINGLE UINT64_C(0x0010000000000000) /* LV - also a PV flag */
|
#define LV_CACHE_VOL UINT64_C(0x0010000000000000) /* LV - also a PV flag */
|
||||||
|
|
||||||
|
|
||||||
/* Format features flags */
|
/* Format features flags */
|
||||||
@ -248,11 +248,11 @@
|
|||||||
|
|
||||||
#define lv_is_cache(lv) (((lv)->status & CACHE) ? 1 : 0)
|
#define lv_is_cache(lv) (((lv)->status & CACHE) ? 1 : 0)
|
||||||
#define lv_is_cache_pool(lv) (((lv)->status & CACHE_POOL) ? 1 : 0)
|
#define lv_is_cache_pool(lv) (((lv)->status & CACHE_POOL) ? 1 : 0)
|
||||||
#define lv_is_cache_single(lv) (((lv)->status & LV_CACHE_SINGLE) ? 1 : 0)
|
#define lv_is_cache_vol(lv) (((lv)->status & LV_CACHE_VOL) ? 1 : 0)
|
||||||
#define lv_is_used_cache_pool(lv) (lv_is_cache_pool(lv) && !dm_list_empty(&(lv)->segs_using_this_lv))
|
#define lv_is_used_cache_pool(lv) (lv_is_cache_pool(lv) && !dm_list_empty(&(lv)->segs_using_this_lv))
|
||||||
#define lv_is_cache_pool_data(lv) (((lv)->status & CACHE_POOL_DATA) ? 1 : 0)
|
#define lv_is_cache_pool_data(lv) (((lv)->status & CACHE_POOL_DATA) ? 1 : 0)
|
||||||
#define lv_is_cache_pool_metadata(lv) (((lv)->status & CACHE_POOL_METADATA) ? 1 : 0)
|
#define lv_is_cache_pool_metadata(lv) (((lv)->status & CACHE_POOL_METADATA) ? 1 : 0)
|
||||||
#define lv_is_cache_type(lv) (((lv)->status & (CACHE | CACHE_POOL | LV_CACHE_SINGLE | CACHE_POOL_DATA | CACHE_POOL_METADATA)) ? 1 : 0)
|
#define lv_is_cache_type(lv) (((lv)->status & (CACHE | CACHE_POOL | LV_CACHE_VOL | CACHE_POOL_DATA | CACHE_POOL_METADATA)) ? 1 : 0)
|
||||||
|
|
||||||
#define lv_is_pool(lv) (((lv)->status & (CACHE_POOL | THIN_POOL)) ? 1 : 0)
|
#define lv_is_pool(lv) (((lv)->status & (CACHE_POOL | THIN_POOL)) ? 1 : 0)
|
||||||
#define lv_is_pool_data(lv) (((lv)->status & (CACHE_POOL_DATA | THIN_POOL_DATA)) ? 1 : 0)
|
#define lv_is_pool_data(lv) (((lv)->status & (CACHE_POOL_DATA | THIN_POOL_DATA)) ? 1 : 0)
|
||||||
@ -1254,7 +1254,7 @@ int cache_set_params(struct lv_segment *seg,
|
|||||||
cache_mode_t mode,
|
cache_mode_t mode,
|
||||||
const char *policy_name,
|
const char *policy_name,
|
||||||
const struct dm_config_tree *policy_settings);
|
const struct dm_config_tree *policy_settings);
|
||||||
int cache_single_set_params(struct cmd_context *cmd,
|
int cache_vol_set_params(struct cmd_context *cmd,
|
||||||
struct logical_volume *cache_lv,
|
struct logical_volume *cache_lv,
|
||||||
struct logical_volume *pool_lv,
|
struct logical_volume *pool_lv,
|
||||||
uint64_t poolmetadatasize,
|
uint64_t poolmetadatasize,
|
||||||
@ -1279,7 +1279,7 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
|
|||||||
struct logical_volume *origin_lv);
|
struct logical_volume *origin_lv);
|
||||||
int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean);
|
int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean);
|
||||||
int lv_cache_remove(struct logical_volume *cache_lv);
|
int lv_cache_remove(struct logical_volume *cache_lv);
|
||||||
int lv_detach_cache_single(struct logical_volume *cache_lv);
|
int lv_detach_cache_vol(struct logical_volume *cache_lv);
|
||||||
int wipe_cache_pool(struct logical_volume *cache_pool_lv);
|
int wipe_cache_pool(struct logical_volume *cache_pool_lv);
|
||||||
/* -- metadata/cache_manip.c */
|
/* -- metadata/cache_manip.c */
|
||||||
|
|
||||||
|
@ -1430,7 +1430,7 @@ static int _cache_settings_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
struct _str_list_append_baton baton;
|
struct _str_list_append_baton baton;
|
||||||
struct dm_list dummy_list; /* dummy list to display "nothing" */
|
struct dm_list dummy_list; /* dummy list to display "nothing" */
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -1568,7 +1568,7 @@ static int _cache_policy_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
const struct lv_segment *seg = (const struct lv_segment *) data;
|
const struct lv_segment *seg = (const struct lv_segment *) data;
|
||||||
const struct lv_segment *setting_seg = NULL;
|
const struct lv_segment *setting_seg = NULL;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -2753,7 +2753,7 @@ static int _cachemetadataformat_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
const struct lv_segment *setting_seg = NULL;
|
const struct lv_segment *setting_seg = NULL;
|
||||||
const uint64_t *fmt;
|
const uint64_t *fmt;
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
@ -3231,7 +3231,7 @@ static int _lvmetadatasize_disp(struct dm_report *rh, struct dm_pool *mem,
|
|||||||
const struct logical_volume *lv = (const struct logical_volume *) data;
|
const struct logical_volume *lv = (const struct logical_volume *) data;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(first_seg(lv)->pool_lv)) {
|
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv)) {
|
||||||
size = lv_metadata_size(lv);
|
size = lv_metadata_size(lv);
|
||||||
return _size64_disp(rh, mem, field, &size, private);
|
return _size64_disp(rh, mem, field, &size, private);
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,15 @@ desired caching type, and specify the fast LV to use:
|
|||||||
.nf
|
.nf
|
||||||
using dm-cache:
|
using dm-cache:
|
||||||
|
|
||||||
$ lvconvert --type cache --cachepool fast vg/main
|
$ lvconvert --type cache --cachevol fast vg/main
|
||||||
|
|
||||||
or dm-writecache:
|
using dm-writecache:
|
||||||
|
|
||||||
$ lvconvert --type writecache --cachepool fast vg/main
|
$ lvconvert --type writecache --cachevol fast vg/main
|
||||||
|
|
||||||
|
using dm-cache with a cache pool:
|
||||||
|
|
||||||
|
$ lvconvert --type cache --cachepool fastpool vg/main
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
.B 4. Display LVs
|
.B 4. Display LVs
|
||||||
@ -82,7 +86,7 @@ using dm-cache:
|
|||||||
main vg Cwi-a-C--- [main_corig] cache main_corig(0)
|
main vg Cwi-a-C--- [main_corig] cache main_corig(0)
|
||||||
[main_corig] vg owi-aoC--- linear /dev/slow(0)
|
[main_corig] vg owi-aoC--- linear /dev/slow(0)
|
||||||
|
|
||||||
or dm-writecache:
|
using dm-writecache:
|
||||||
|
|
||||||
$ lvs -a -o name,vgname,lvattr,origin,segtype,devices vg
|
$ lvs -a -o name,vgname,lvattr,origin,segtype,devices vg
|
||||||
LV VG Attr Origin Type Devices
|
LV VG Attr Origin Type Devices
|
||||||
@ -110,6 +114,32 @@ attached.
|
|||||||
|
|
||||||
\&
|
\&
|
||||||
|
|
||||||
|
.SS option args
|
||||||
|
|
||||||
|
\&
|
||||||
|
|
||||||
|
.B --cachevol
|
||||||
|
.I LV
|
||||||
|
.br
|
||||||
|
|
||||||
|
Pass this option a standard LV. With a cache vol, cache data and metadata
|
||||||
|
are contained within the single LV. This is used with dm-writecache or
|
||||||
|
dm-cache.
|
||||||
|
|
||||||
|
.B --cachepool
|
||||||
|
.IR CachePoolLV | LV
|
||||||
|
.br
|
||||||
|
|
||||||
|
Pass this option a cache pool object. With a cache pool, lvm places cache
|
||||||
|
data and cache metadata on different LVs. The two LVs together are called
|
||||||
|
a cache pool. This permits specific placement of data and metadata. A
|
||||||
|
cache pool is represented as a special type of LV that cannot be used
|
||||||
|
directly. (If a standard LV is passed to this option, lvm will first
|
||||||
|
convert it to a cache pool by combining it with another LV to use for
|
||||||
|
metadata.) This can be used with dm-cache.
|
||||||
|
|
||||||
|
\&
|
||||||
|
|
||||||
.SS dm-writecache block size
|
.SS dm-writecache block size
|
||||||
|
|
||||||
\&
|
\&
|
||||||
@ -145,7 +175,7 @@ Tunable parameters can be passed to the dm-writecache kernel module using
|
|||||||
the --cachesettings option when caching is started, e.g.
|
the --cachesettings option when caching is started, e.g.
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
$ lvconvert --type writecache --cachepool fast \\
|
$ lvconvert --type writecache --cachevol fast \\
|
||||||
--cachesettings 'high_watermark=N writeback_jobs=N' vg/main
|
--cachesettings 'high_watermark=N writeback_jobs=N' vg/main
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
@ -201,10 +231,10 @@ Applicable only to persistent memory.
|
|||||||
\&
|
\&
|
||||||
|
|
||||||
When using dm-cache, the cache metadata and cache data can be stored on
|
When using dm-cache, the cache metadata and cache data can be stored on
|
||||||
separate LVs. To do this, a "cache-pool LV" is created, which is a
|
separate LVs. To do this, a "cache pool" is created, which is a special
|
||||||
special LV that references two sub LVs, one for data and one for metadata.
|
LV that references two sub LVs, one for data and one for metadata.
|
||||||
|
|
||||||
To create a cache-pool LV from two separate LVs:
|
To create a cache pool from two separate LVs:
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
$ lvcreate -n fastpool -L DataSize vg /dev/fast1
|
$ lvcreate -n fastpool -L DataSize vg /dev/fast1
|
||||||
@ -212,17 +242,17 @@ $ lvcreate -n fastpoolmeta -L MetadataSize vg /dev/fast2
|
|||||||
$ lvconvert --type cache-pool --poolmetadata fastpoolmeta vg/fastpool
|
$ lvconvert --type cache-pool --poolmetadata fastpoolmeta vg/fastpool
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Then use the cache-pool LV to start caching the main LV:
|
Then use the cache pool LV to start caching the main LV:
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
$ lvconvert --type cache --cachepool fastpool vg/main
|
$ lvconvert --type cache --cachepool fastpool vg/main
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
A variation of the same procedure automatically creates a cache-pool when
|
A variation of the same procedure automatically creates a cache pool when
|
||||||
caching is started. To do this, use a standard LV as the --cachepool
|
caching is started. To do this, use a standard LV as the --cachepool
|
||||||
(this will hold cache data), and use another standard LV as the
|
(this will hold cache data), and use another standard LV as the
|
||||||
--poolmetadata (this will hold cache metadata). LVM will create a
|
--poolmetadata (this will hold cache metadata). LVM will create a
|
||||||
cache-pool LV from the two specified LVs, and use the cache-pool to start
|
cache pool LV from the two specified LVs, and use the cache pool to start
|
||||||
caching the main LV.
|
caching the main LV.
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
@ -257,7 +287,7 @@ mode can be displayed with the cache_mode reporting option:
|
|||||||
defines the default cache mode.
|
defines the default cache mode.
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
$ lvconvert --type cache --cachepool fast \\
|
$ lvconvert --type cache --cachevol fast \\
|
||||||
--cachemode writethrough vg/main
|
--cachemode writethrough vg/main
|
||||||
.nf
|
.nf
|
||||||
|
|
||||||
@ -360,9 +390,36 @@ and metadata LVs, each of the sub-LVs can use raid1.)
|
|||||||
.nf
|
.nf
|
||||||
$ lvcreate -n main -L Size vg /dev/slow
|
$ lvcreate -n main -L Size vg /dev/slow
|
||||||
$ lvcreate --type raid1 -m 1 -n fast -L Size vg /dev/fast1 /dev/fast2
|
$ lvcreate --type raid1 -m 1 -n fast -L Size vg /dev/fast1 /dev/fast2
|
||||||
$ lvconvert --type cache --cachepool fast vg/main
|
$ lvconvert --type cache --cachevol fast vg/main
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
.SS dm-cache command shortcut
|
||||||
|
|
||||||
|
\&
|
||||||
|
|
||||||
|
A single command can be used to create a cache pool and attach that new
|
||||||
|
cache pool to a main LV:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
$ lvcreate --type cache --name Name --size Size VG/LV [PV]
|
||||||
|
.fi
|
||||||
|
|
||||||
|
In this command, the specified LV already exists, and is the main LV to be
|
||||||
|
cached. The command creates a new cache pool with the given name and
|
||||||
|
size, using the optionally specified PV (typically an ssd). Then it
|
||||||
|
attaches the new cache pool to the existing main LV to begin caching.
|
||||||
|
|
||||||
|
(Note: ensure that the specified main LV is a standard LV. If a cache
|
||||||
|
pool LV is mistakenly specified, then the command does something
|
||||||
|
different.)
|
||||||
|
|
||||||
|
(Note: the type option is interpreted differently by this command than by
|
||||||
|
normal lvcreate commands in which --type specifies the type of the newly
|
||||||
|
created LV. In this case, an LV with type cache-pool is being created,
|
||||||
|
and the existing main LV is being converted to type cache.)
|
||||||
|
|
||||||
|
\&
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR lvm.conf (5),
|
.BR lvm.conf (5),
|
||||||
.BR lvchange (8),
|
.BR lvchange (8),
|
||||||
|
@ -69,13 +69,13 @@ mount_umount()
|
|||||||
#
|
#
|
||||||
|
|
||||||
# 1 shouldn't be used any longer
|
# 1 shouldn't be used any longer
|
||||||
not lvconvert --cachemetadataformat 1 -y --type cache --cachepool $lv2 $vg/$lv1
|
not lvconvert --cachemetadataformat 1 -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
# 3 doesn't exist
|
# 3 doesn't exist
|
||||||
not lvconvert --cachemetadataformat 3 -y --type cache --cachepool $lv2 $vg/$lv1
|
not lvconvert --cachemetadataformat 3 -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
# 2 is used by default
|
# 2 is used by default
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemetadataformat "2"
|
check lv_field $vg/$lv1 cachemetadataformat "2"
|
||||||
|
|
||||||
@ -84,14 +84,14 @@ check lv_field $vg/$lv1 segtype linear
|
|||||||
check lv_field $vg/$lv2 segtype linear
|
check lv_field $vg/$lv2 segtype linear
|
||||||
|
|
||||||
# 2 can be set explicitly
|
# 2 can be set explicitly
|
||||||
lvconvert --cachemetadataformat 2 -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert --cachemetadataformat 2 -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemetadataformat "2"
|
check lv_field $vg/$lv1 cachemetadataformat "2"
|
||||||
|
|
||||||
lvconvert --splitcache $vg/$lv1
|
lvconvert --splitcache $vg/$lv1
|
||||||
|
|
||||||
# "auto" means 2
|
# "auto" means 2
|
||||||
lvconvert --cachemetadataformat auto -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert --cachemetadataformat auto -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemetadataformat "2"
|
check lv_field $vg/$lv1 cachemetadataformat "2"
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ mount_umount $lv1
|
|||||||
# Test --poolmetadatasize
|
# Test --poolmetadatasize
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --poolmetadatasize 4m $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --poolmetadatasize 4m $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 lv_metadata_size "4.00m"
|
check lv_field $vg/$lv1 lv_metadata_size "4.00m"
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ mount_umount $lv1
|
|||||||
# Test --chunksize
|
# Test --chunksize
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --chunksize 32k $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --chunksize 32k $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 chunksize "32.00k"
|
check lv_field $vg/$lv1 chunksize "32.00k"
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ mount_umount $lv1
|
|||||||
# Test --cachemode
|
# Test --cachemode
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --cachemode writethrough $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --cachemode writethrough $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemode "writethrough"
|
check lv_field $vg/$lv1 cachemode "writethrough"
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ mount_umount $lv1
|
|||||||
|
|
||||||
# FIXME: kernel errors for other cache modes
|
# FIXME: kernel errors for other cache modes
|
||||||
|
|
||||||
#lvconvert -y --type cache --cachepool $lv2 --cachemode passthrough $vg/$lv1
|
#lvconvert -y --type cache --cachevol $lv2 --cachemode passthrough $vg/$lv1
|
||||||
|
|
||||||
#check lv_field $vg/$lv1 cachemode "passthrough"
|
#check lv_field $vg/$lv1 cachemode "passthrough"
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ mount_umount $lv1
|
|||||||
#mount_umount $lv1
|
#mount_umount $lv1
|
||||||
|
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --cachemode writeback $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --cachemode writeback $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemode "writeback"
|
check lv_field $vg/$lv1 cachemode "writeback"
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ mount_umount $lv1
|
|||||||
# Test --cachepolicy
|
# Test --cachepolicy
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --cachepolicy smq $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --cachepolicy smq $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachepolicy "smq"
|
check lv_field $vg/$lv1 cachepolicy "smq"
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ mount_umount $lv1
|
|||||||
# (only for mq policy, no settings for smq)
|
# (only for mq policy, no settings for smq)
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 --cachemode writethrough --cachepolicy mq --cachesettings 'migration_threshold = 233 sequential_threshold=13 random_threshold =1' $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 --cachemode writethrough --cachepolicy mq --cachesettings 'migration_threshold = 233 sequential_threshold=13 random_threshold =1' $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 cachemode "writethrough"
|
check lv_field $vg/$lv1 cachemode "writethrough"
|
||||||
check lv_field $vg/$lv1 cachepolicy "mq"
|
check lv_field $vg/$lv1 cachepolicy "mq"
|
||||||
@ -224,7 +224,7 @@ mount_umount $lv1
|
|||||||
# Test lvchange of --cachemode, --cachepolicy, --cachesettings
|
# Test lvchange of --cachemode, --cachepolicy, --cachesettings
|
||||||
#
|
#
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
lvchange -ay $vg/$lv1
|
lvchange -ay $vg/$lv1
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
|
|||||||
lvcreate -L10 -an -n $lv1 $vg "$dev1"
|
lvcreate -L10 -an -n $lv1 $vg "$dev1"
|
||||||
lvcreate -L10 -an -n $lv2 $vg "$dev2"
|
lvcreate -L10 -an -n $lv2 $vg "$dev2"
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
lvconvert -y --type thin-pool $vg/$lv1
|
lvconvert -y --type thin-pool $vg/$lv1
|
||||||
|
|
||||||
lvcreate --type thin -V10 -n lvthin --thinpool $vg/$lv1
|
lvcreate --type thin -V10 -n lvthin --thinpool $vg/$lv1
|
||||||
|
@ -45,7 +45,7 @@ cp pattern1 "$mount_dir/pattern1"
|
|||||||
umount "$mount_dir"
|
umount "$mount_dir"
|
||||||
lvchange -an $vg/$lv1
|
lvchange -an $vg/$lv1
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 segtype cache
|
check lv_field $vg/$lv1 segtype cache
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ cp pattern1 "$mount_dir/pattern1"
|
|||||||
umount "$mount_dir"
|
umount "$mount_dir"
|
||||||
lvchange -an $vg/$lv1
|
lvchange -an $vg/$lv1
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 segtype cache
|
check lv_field $vg/$lv1 segtype cache
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ lvchange -an $vg/$lv2
|
|||||||
|
|
||||||
# test2: create fs on LV after cache is attached
|
# test2: create fs on LV after cache is attached
|
||||||
|
|
||||||
lvconvert -y --type cache --cachepool $lv2 $vg/$lv1
|
lvconvert -y --type cache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 segtype cache
|
check lv_field $vg/$lv1 segtype cache
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ cp pattern1 $mount_dir/pattern1
|
|||||||
umount $mount_dir
|
umount $mount_dir
|
||||||
lvchange -an $vg/$lv1
|
lvchange -an $vg/$lv1
|
||||||
|
|
||||||
lvconvert --yes --type writecache --cachepool $lv2 $vg/$lv1
|
lvconvert --yes --type writecache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 segtype writecache
|
check lv_field $vg/$lv1 segtype writecache
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ lvchange -an $vg/$lv2
|
|||||||
|
|
||||||
# test2: create fs on LV after writecache is attached
|
# test2: create fs on LV after writecache is attached
|
||||||
|
|
||||||
lvconvert --yes --type writecache --cachepool $lv2 $vg/$lv1
|
lvconvert --yes --type writecache --cachevol $lv2 $vg/$lv1
|
||||||
|
|
||||||
check lv_field $vg/$lv1 segtype writecache
|
check lv_field $vg/$lv1 segtype writecache
|
||||||
|
|
||||||
|
@ -121,7 +121,10 @@ arg(cachemode_ARG, '\0', "cachemode", cachemode_VAL, 0, 0,
|
|||||||
"block invalidates. See \\fBlvmcache\\fP(7) for more information.\n")
|
"block invalidates. See \\fBlvmcache\\fP(7) for more information.\n")
|
||||||
|
|
||||||
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0,
|
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0,
|
||||||
"The name of a cache pool LV.\n")
|
"The name of a cache pool.\n")
|
||||||
|
|
||||||
|
arg(cachevol_ARG, '\0', "cachevol", lv_VAL, 0, 0,
|
||||||
|
"The name of a cache volume.\n")
|
||||||
|
|
||||||
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
|
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
|
||||||
"The command profile to use for command configuration.\n"
|
"The command profile to use for command configuration.\n"
|
||||||
|
@ -453,30 +453,38 @@ RULE: --poolmetadata not --readahead --stripesize --stripes_long
|
|||||||
|
|
||||||
lvconvert --type cache --cachepool LV LV_linear_striped_raid_thinpool
|
lvconvert --type cache --cachepool LV LV_linear_striped_raid_thinpool
|
||||||
OO: --cache, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
|
OO: --cache, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||||
ID: lvconvert_to_cache_vol
|
ID: lvconvert_to_cache_with_cachepool
|
||||||
DESC: Attach a cache to an LV, converts the LV to type cache.
|
DESC: Attach a cache pool to an LV, converts the LV to type cache.
|
||||||
RULE: all and lv_is_visible
|
RULE: all and lv_is_visible
|
||||||
RULE: --poolmetadata not --readahead --stripesize --stripes_long
|
RULE: --poolmetadata not --readahead --stripesize --stripes_long
|
||||||
|
|
||||||
# alternate form of lvconvert --type cache
|
# alternate form of lvconvert --type cache
|
||||||
lvconvert --cache --cachepool LV LV_linear_striped_raid_thinpool
|
lvconvert --cache --cachepool LV LV_linear_striped_raid_thinpool
|
||||||
OO: --type cache, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
|
OO: --type cache, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||||
ID: lvconvert_to_cache_vol
|
ID: lvconvert_to_cache_with_cachepool
|
||||||
DESC: Attach a cache to an LV (infers --type cache).
|
DESC: Attach a cache pool to an LV (infers --type cache).
|
||||||
RULE: all and lv_is_visible
|
RULE: all and lv_is_visible
|
||||||
RULE: --poolmetadata not --readahead --stripesize --stripes_long
|
RULE: --poolmetadata not --readahead --stripesize --stripes_long
|
||||||
FLAGS: SECONDARY_SYNTAX
|
FLAGS: SECONDARY_SYNTAX
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
lvconvert --type writecache --cachepool LV LV_linear_striped_raid
|
lvconvert --type writecache --cachevol LV LV_linear_striped_raid
|
||||||
OO: OO_LVCONVERT, --cachesettings String
|
OO: OO_LVCONVERT, --cachesettings String
|
||||||
ID: lvconvert_to_writecache_vol
|
ID: lvconvert_to_writecache
|
||||||
DESC: Attach a writecache to an LV, converts the LV to type writecache.
|
DESC: Attach a writecache to an LV, converts the LV to type writecache.
|
||||||
RULE: all and lv_is_visible
|
RULE: all and lv_is_visible
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
lvconvert --type cache --cachevol LV LV_linear_striped_raid_thinpool
|
||||||
|
OO: --cache, OO_LVCONVERT_CACHE, OO_LVCONVERT, --poolmetadatasize SizeMB, --chunksize SizeKB
|
||||||
|
ID: lvconvert_to_cache_with_cachevol
|
||||||
|
DESC: Attach a cache to an LV, converts the LV to type cache.
|
||||||
|
RULE: all and lv_is_visible
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
lvconvert --type thin-pool LV_linear_striped_raid_cache
|
lvconvert --type thin-pool LV_linear_striped_raid_cache
|
||||||
OO: --stripes_long Number, --stripesize SizeKB,
|
OO: --stripes_long Number, --stripesize SizeKB,
|
||||||
--discards Discards, OO_LVCONVERT_POOL, OO_LVCONVERT
|
--discards Discards, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||||
|
@ -621,7 +621,7 @@ static int _lvchange_cache(struct cmd_context *cmd,
|
|||||||
|
|
||||||
seg = first_seg(lv);
|
seg = first_seg(lv);
|
||||||
|
|
||||||
if (seg_is_cache(seg) && lv_is_cache_single(seg->pool_lv))
|
if (seg_is_cache(seg) && lv_is_cache_vol(seg->pool_lv))
|
||||||
setting_seg = seg;
|
setting_seg = seg;
|
||||||
|
|
||||||
else if (seg_is_cache_pool(seg))
|
else if (seg_is_cache_pool(seg))
|
||||||
|
@ -1847,8 +1847,8 @@ static int _lvconvert_split_and_keep_cache(struct cmd_context *cmd,
|
|||||||
if (!archive(lv->vg))
|
if (!archive(lv->vg))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (lv_is_cache_single(cache_seg->pool_lv)) {
|
if (lv_is_cache_vol(cache_seg->pool_lv)) {
|
||||||
if (!lv_detach_cache_single(lv))
|
if (!lv_detach_cache_vol(lv))
|
||||||
return_0;
|
return_0;
|
||||||
} else {
|
} else {
|
||||||
if (!lv_cache_remove(lv))
|
if (!lv_cache_remove(lv))
|
||||||
@ -2421,7 +2421,7 @@ static int _lvconvert_cache_repair(struct cmd_context *cmd,
|
|||||||
struct logical_volume *pmslv;
|
struct logical_volume *pmslv;
|
||||||
struct logical_volume *mlv;
|
struct logical_volume *mlv;
|
||||||
|
|
||||||
if (lv_is_cache(cache_lv) && lv_is_cache_single(first_seg(cache_lv)->pool_lv)) {
|
if (lv_is_cache(cache_lv) && lv_is_cache_vol(first_seg(cache_lv)->pool_lv)) {
|
||||||
log_error("Manual repair required.");
|
log_error("Manual repair required.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3354,7 +3354,7 @@ revert_new_lv:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cache_single_attach(struct cmd_context *cmd,
|
static int _cache_vol_attach(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct logical_volume *lv_fast)
|
struct logical_volume *lv_fast)
|
||||||
{
|
{
|
||||||
@ -3398,7 +3398,7 @@ static int _cache_single_attach(struct cmd_context *cmd,
|
|||||||
if (arg_is_set(cmd, poolmetadatasize_ARG))
|
if (arg_is_set(cmd, poolmetadatasize_ARG))
|
||||||
poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, 0);
|
poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, 0);
|
||||||
|
|
||||||
if (!cache_single_set_params(cmd, cache_lv, lv_fast, poolmetadatasize, chunk_size, cache_metadata_format, cache_mode, policy_name, policy_settings))
|
if (!cache_vol_set_params(cmd, cache_lv, lv_fast, poolmetadatasize, chunk_size, cache_metadata_format, cache_mode, policy_name, policy_settings))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4104,7 +4104,72 @@ int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
NULL, NULL, &_lvconvert_to_pool_single);
|
NULL, NULL, &_lvconvert_to_pool_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lvconvert_cache_attach_single(struct cmd_context *cmd,
|
static int _lvconvert_cachevol_attach_single(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv,
|
||||||
|
struct processing_handle *handle)
|
||||||
|
{
|
||||||
|
struct volume_group *vg = lv->vg;
|
||||||
|
struct logical_volume *cachevol_lv;
|
||||||
|
const char *cachevol_name;
|
||||||
|
|
||||||
|
if (!(cachevol_name = arg_str_value(cmd, cachevol_ARG, NULL)))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
if (!validate_lvname_param(cmd, &vg->name, &cachevol_name))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
if (!(cachevol_lv = find_lv(vg, cachevol_name))) {
|
||||||
|
log_error("Cache single %s not found.", cachevol_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the LV is not active elsewhere. */
|
||||||
|
if (!lockd_lv(cmd, lv, "ex", 0))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
if (!dm_list_empty(&cachevol_lv->segs_using_this_lv)) {
|
||||||
|
log_error("LV %s is already in use.", display_lvname(cachevol_lv));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg_is_set(cmd, yes_ARG) &&
|
||||||
|
yes_no_prompt("Erase all existing data on %s? [y/n]: ", display_lvname(cachevol_lv)) == 'n') {
|
||||||
|
log_error("Conversion aborted.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the LV is not active elsewhere. */
|
||||||
|
if (!lockd_lv(cmd, cachevol_lv, "ex", LDLV_PERSISTENT))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
cachevol_lv->status |= LV_CACHE_VOL;
|
||||||
|
|
||||||
|
if (!wipe_cache_pool(cachevol_lv))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
/* When the lv arg is a thinpool, redirect command to data sub lv. */
|
||||||
|
|
||||||
|
if (lv_is_thin_pool(lv)) {
|
||||||
|
lv = seg_lv(first_seg(lv), 0);
|
||||||
|
log_verbose("Redirecting operation to data sub LV %s.", display_lvname(lv));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_raid_split_image_conversion(lv))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
/* Attach the cache to the main LV. */
|
||||||
|
|
||||||
|
if (!_cache_vol_attach(cmd, lv, cachevol_lv))
|
||||||
|
goto_out;
|
||||||
|
|
||||||
|
log_print_unless_silent("Logical volume %s is now cached.", display_lvname(lv));
|
||||||
|
|
||||||
|
return ECMD_PROCESSED;
|
||||||
|
out:
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _lvconvert_cachepool_attach_single(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct processing_handle *handle)
|
struct processing_handle *handle)
|
||||||
{
|
{
|
||||||
@ -4132,7 +4197,7 @@ static int _lvconvert_cache_attach_single(struct cmd_context *cmd,
|
|||||||
* If using an existing cache pool, wipe it.
|
* If using an existing cache pool, wipe it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!lv_is_cache_pool(cachepool_lv) && arg_is_set(cmd, poolmetadata_ARG)) {
|
if (!lv_is_cache_pool(cachepool_lv)) {
|
||||||
int lvt_enum = get_lvt_enum(cachepool_lv);
|
int lvt_enum = get_lvt_enum(cachepool_lv);
|
||||||
struct lv_type *lvtype = get_lv_type(lvt_enum);
|
struct lv_type *lvtype = get_lv_type(lvt_enum);
|
||||||
|
|
||||||
@ -4163,28 +4228,6 @@ static int _lvconvert_cache_attach_single(struct cmd_context *cmd,
|
|||||||
log_error("LV %s is not a cache pool.", display_lvname(cachepool_lv));
|
log_error("LV %s is not a cache pool.", display_lvname(cachepool_lv));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!lv_is_cache_pool(cachepool_lv)) {
|
|
||||||
|
|
||||||
if (!dm_list_empty(&cachepool_lv->segs_using_this_lv)) {
|
|
||||||
log_error("LV %s is already in use.", display_lvname(cachepool_lv));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arg_is_set(cmd, yes_ARG) &&
|
|
||||||
yes_no_prompt("Erase all existing data on %s? [y/n]: ", display_lvname(cachepool_lv)) == 'n') {
|
|
||||||
log_error("Conversion aborted.");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the LV is not active elsewhere. */
|
|
||||||
if (!lockd_lv(cmd, cachepool_lv, "ex", LDLV_PERSISTENT))
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
cachepool_lv->status |= LV_CACHE_SINGLE;
|
|
||||||
|
|
||||||
if (!wipe_cache_pool(cachepool_lv))
|
|
||||||
goto_out;
|
|
||||||
} else {
|
} else {
|
||||||
if (!dm_list_empty(&cachepool_lv->segs_using_this_lv)) {
|
if (!dm_list_empty(&cachepool_lv->segs_using_this_lv)) {
|
||||||
log_error("Cache pool %s is already in use.", cachepool_name);
|
log_error("Cache pool %s is already in use.", cachepool_name);
|
||||||
@ -4225,31 +4268,20 @@ static int _lvconvert_cache_attach_single(struct cmd_context *cmd,
|
|||||||
|
|
||||||
/* Attach the cache to the main LV. */
|
/* Attach the cache to the main LV. */
|
||||||
|
|
||||||
if (lv_is_cache_single(cachepool_lv)) {
|
if (!_cache_pool_attach(cmd, lv, cachepool_lv))
|
||||||
if (!_cache_single_attach(cmd, lv, cachepool_lv))
|
goto_out;
|
||||||
goto_out;
|
|
||||||
|
|
||||||
} else if (lv_is_cache_pool(cachepool_lv)) {
|
|
||||||
if (!_cache_pool_attach(cmd, lv, cachepool_lv))
|
|
||||||
goto_out;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log_error(INTERNAL_ERROR "Invalid cache pool state for %s", cachepool_lv->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_print_unless_silent("Logical volume %s is now cached.", display_lvname(lv));
|
log_print_unless_silent("Logical volume %s is now cached.", display_lvname(lv));
|
||||||
|
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lvconvert_to_cache_vol_cmd(struct cmd_context *cmd, int argc, char **argv)
|
int lvconvert_to_cache_with_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||||
{
|
{
|
||||||
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
|
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
|
||||||
NULL, NULL, &_lvconvert_cache_attach_single);
|
NULL, NULL, &_lvconvert_cachepool_attach_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lvconvert_to_thin_with_external_single(struct cmd_context *cmd,
|
static int _lvconvert_to_thin_with_external_single(struct cmd_context *cmd,
|
||||||
@ -4510,7 +4542,7 @@ static int _lvconvert_detach_writecache(struct cmd_context *cmd,
|
|||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct logical_volume *lv_fast);
|
struct logical_volume *lv_fast);
|
||||||
|
|
||||||
static int _lvconvert_split_cache_single(struct cmd_context *cmd,
|
static int _lvconvert_split_cache_vol(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv,
|
||||||
struct processing_handle *handle)
|
struct processing_handle *handle)
|
||||||
{
|
{
|
||||||
@ -4565,7 +4597,7 @@ static int _lvconvert_split_cache_single(struct cmd_context *cmd,
|
|||||||
|
|
||||||
} else if (lv_is_cache(lv_main)) {
|
} else if (lv_is_cache(lv_main)) {
|
||||||
if ((cmd->command->command_enum == lvconvert_split_and_remove_cache_CMD) &&
|
if ((cmd->command->command_enum == lvconvert_split_and_remove_cache_CMD) &&
|
||||||
lv_is_cache_single(lv_fast)) {
|
lv_is_cache_vol(lv_fast)) {
|
||||||
log_error("Detach cache from %s with --splitcache.", display_lvname(lv));
|
log_error("Detach cache from %s with --splitcache.", display_lvname(lv));
|
||||||
log_error("The cache %s may then be removed with lvremove.", display_lvname(lv_fast));
|
log_error("The cache %s may then be removed with lvremove.", display_lvname(lv_fast));
|
||||||
return 0;
|
return 0;
|
||||||
@ -4600,7 +4632,7 @@ int lvconvert_split_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
|
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
|
||||||
NULL, NULL, &_lvconvert_split_cache_single);
|
NULL, NULL, &_lvconvert_split_cache_vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _lvconvert_raid_types_single(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _lvconvert_raid_types_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
@ -5453,7 +5485,7 @@ static int _lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
|||||||
char *lockd_fast_name = NULL;
|
char *lockd_fast_name = NULL;
|
||||||
struct id lockd_fast_id;
|
struct id lockd_fast_id;
|
||||||
|
|
||||||
fast_name = arg_str_value(cmd, cachepool_ARG, "");
|
fast_name = arg_str_value(cmd, cachevol_ARG, "");
|
||||||
|
|
||||||
if (!(lv_fast = find_lv(vg, fast_name))) {
|
if (!(lv_fast = find_lv(vg, fast_name))) {
|
||||||
log_error("LV %s not found.", fast_name);
|
log_error("LV %s not found.", fast_name);
|
||||||
@ -5559,7 +5591,7 @@ bad:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lvconvert_to_writecache_vol_cmd(struct cmd_context *cmd, int argc, char **argv)
|
int lvconvert_to_writecache_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct processing_handle *handle;
|
struct processing_handle *handle;
|
||||||
struct lvconvert_result lr = { 0 };
|
struct lvconvert_result lr = { 0 };
|
||||||
@ -5582,6 +5614,29 @@ int lvconvert_to_writecache_vol_cmd(struct cmd_context *cmd, int argc, char **ar
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lvconvert_to_cache_with_cachevol_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct processing_handle *handle;
|
||||||
|
struct lvconvert_result lr = { 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!(handle = init_processing_handle(cmd, NULL))) {
|
||||||
|
log_error("Failed to initialize processing handle.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->custom_handle = &lr;
|
||||||
|
|
||||||
|
cmd->cname->flags &= ~GET_VGNAME_FROM_OPTIONS;
|
||||||
|
|
||||||
|
ret = process_each_lv(cmd, cmd->position_argc, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE, handle, NULL,
|
||||||
|
&_lvconvert_cachevol_attach_single);
|
||||||
|
|
||||||
|
destroy_processing_handle(cmd, handle);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All lvconvert command defs have their own function,
|
* All lvconvert command defs have their own function,
|
||||||
* so the generic function name is unused.
|
* so the generic function name is unused.
|
||||||
|
@ -123,8 +123,9 @@ static const struct command_function _command_functions[CMD_COUNT] = {
|
|||||||
{ lvconvert_to_thinpool_CMD, lvconvert_to_pool_cmd },
|
{ lvconvert_to_thinpool_CMD, lvconvert_to_pool_cmd },
|
||||||
{ lvconvert_to_cachepool_CMD, lvconvert_to_pool_cmd },
|
{ lvconvert_to_cachepool_CMD, lvconvert_to_pool_cmd },
|
||||||
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_cmd },
|
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_cmd },
|
||||||
{ lvconvert_to_cache_vol_CMD, lvconvert_to_cache_vol_cmd },
|
{ lvconvert_to_cache_with_cachevol_CMD, lvconvert_to_cache_with_cachevol_cmd },
|
||||||
{ lvconvert_to_writecache_vol_CMD, lvconvert_to_writecache_vol_cmd },
|
{ lvconvert_to_cache_with_cachepool_CMD, lvconvert_to_cache_with_cachepool_cmd },
|
||||||
|
{ lvconvert_to_writecache_CMD, lvconvert_to_writecache_cmd },
|
||||||
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_cmd },
|
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_cmd },
|
||||||
{ lvconvert_to_thinpool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
{ lvconvert_to_thinpool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
||||||
{ lvconvert_to_cachepool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
{ lvconvert_to_cachepool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
||||||
|
@ -250,8 +250,9 @@ int lvconvert_combine_split_snapshot_cmd(struct cmd_context *cmd, int argc, char
|
|||||||
int lvconvert_start_poll_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_start_poll_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
|
|
||||||
int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
int lvconvert_to_cache_vol_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_to_cache_with_cachevol_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
int lvconvert_to_writecache_vol_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_to_cache_with_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
|
int lvconvert_to_writecache_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
int lvconvert_to_thin_with_external_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_to_thin_with_external_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
int lvconvert_to_pool_or_swap_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
int lvconvert_to_pool_or_swap_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||||
|
@ -402,7 +402,7 @@ static int _move_cache(struct volume_group *vg_from,
|
|||||||
|
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
if (lv_is_cache(lv) && lv_is_cache_single(seg->pool_lv)) {
|
if (lv_is_cache(lv) && lv_is_cache_vol(seg->pool_lv)) {
|
||||||
log_error("Cannot split while LV %s has cache attached.", display_lvname(lv));
|
log_error("Cannot split while LV %s has cache attached.", display_lvname(lv));
|
||||||
return 0;
|
return 0;
|
||||||
} else if (lv_is_cache(lv)) {
|
} else if (lv_is_cache(lv)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user