From db0de73d6eed04b9209936ae53e4e145413c52dc Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Thu, 14 Dec 2023 14:20:19 +0100 Subject: [PATCH] vdo: support creation of compressed thin-pools Add code to handle creation of thin-pool with VDO data backend which can be seen as compressed deduplicated thin-pool. To avoid need of changing to many internal APIs, pass the conversion parameters for create thin-pool data volume via cmd_context. --- lib/commands/toolcontext.c | 2 ++ lib/commands/toolcontext.h | 1 + lib/metadata/pool_manip.c | 3 +++ tools/lvconvert.c | 25 ++++++++++++++++++++++++- tools/lvcreate.c | 15 +++++++++++++-- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index b91a88522..e10938c69 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -1968,6 +1968,8 @@ int refresh_toolcontext(struct cmd_context *cmd) cmd->lib_dir = NULL; + cmd->lvcreate_vcp = NULL; + if (!_init_lvm_conf(cmd)) return_0; diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h index cd91caaef..1ddf17076 100644 --- a/lib/commands/toolcontext.h +++ b/lib/commands/toolcontext.h @@ -281,6 +281,7 @@ struct cmd_context { unsigned rand_seed; struct dm_list pending_delete; /* list of LVs for removal */ struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */ + struct vdo_convert_params *lvcreate_vcp;/* params for LV to VDO conversion */ }; /* diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c index 9e16805b7..105656bca 100644 --- a/lib/metadata/pool_manip.c +++ b/lib/metadata/pool_manip.c @@ -572,6 +572,9 @@ int create_pool(struct logical_volume *pool_lv, if (!lv_add_segment(ah, 0, stripes, pool_lv, striped, stripe_size, 0, 0)) goto_bad; + if (pool_lv->vg->cmd->lvcreate_vcp && !convert_vdo_lv(pool_lv, pool_lv->vg->cmd->lvcreate_vcp)) + goto_bad; + if (!(data_lv = insert_layer_for_lv(pool_lv->vg->cmd, pool_lv, pool_lv->status, (segtype_is_cache_pool(segtype)) ? diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 72e58d466..e50fa666d 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2016 Red Hat, Inc. All rights reserved. + * Copyright (C) 2005-2023 Red Hat, Inc. All rights reserved. * * This file is part of LVM2. * @@ -3063,6 +3063,14 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, thin_zero_t zero_new_blocks; int error_when_full; int data_vdo; + uint64_t vdo_pool_header_size; + struct vdo_convert_params vcp = { + .activate = CHANGE_AN, + .do_zero = 1, + .do_wipe_signatures = 1, + .force = arg_count(cmd, force_ARG), + .yes = arg_count(cmd, yes_ARG), + }; int is_active; int ret = 1; @@ -3359,6 +3367,20 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, goto bad; } + if (data_vdo) { + if (!fill_vdo_target_params(cmd, &vcp.vdo_params, &vdo_pool_header_size, vg->profile)) + goto_bad; + + if (!get_vdo_settings(cmd, &vcp.vdo_params, NULL)) + goto_bad; + + if (data_vdo && lv_is_vdo(lv)) + log_print_unless_silent("Volume %s is already VDO volume, skipping VDO conversion.", + display_lvname(lv)); + else if (!convert_vdo_lv(lv, &vcp)) + goto_bad; + } + pool_lv = lv; } @@ -4847,6 +4869,7 @@ static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd, case striped_LVT: case error_LVT: case zero_LVT: + case vdo_LVT: break; default: bad: diff --git a/tools/lvcreate.c b/tools/lvcreate.c index bbe8bde03..c40c37b9f 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. - * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2023 Red Hat, Inc. All rights reserved. * * This file is part of LVM2. * @@ -720,13 +720,23 @@ static int _read_vdo_params(struct cmd_context *cmd, struct lvcreate_params *lp, struct lvcreate_cmdline_params *lcp) { - if (!seg_is_vdo(lp)) + if (!seg_is_vdo(lp) && + !lp->pool_data_vdo) return 1; // prefiling settings here if (!fill_vdo_target_params(cmd, &lp->vcp.vdo_params, &lp->vdo_pool_header_size, NULL)) return_0; + if (lp->pool_data_vdo) { + lp->vcp.activate = CHANGE_AN; + lp->vcp.do_zero = 1; + lp->vcp.do_wipe_signatures = lp->wipe_signatures; + lp->vcp.force = lp->force; + lp->vcp.yes = lp->force; + cmd->lvcreate_vcp = &lp->vcp; + } + if ((lcp->virtual_size <= DM_VDO_LOGICAL_SIZE_MAXIMUM) && ((lcp->virtual_size + lp->vdo_pool_header_size) > DM_VDO_LOGICAL_SIZE_MAXIMUM)) { log_verbose("Dropping VDO pool header size to 0 to support maximal size %s.", @@ -1056,6 +1066,7 @@ static int _lvcreate_params(struct cmd_context *cmd, POOL_ARGS, SIZE_ARGS, THIN_POOL_ARGS, + VDO_POOL_ARGS, chunksize_ARG, errorwhenfull_ARG, snapshot_ARG,