diff options
Diffstat (limited to 'tools/lvconvert.c')
-rw-r--r-- | tools/lvconvert.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 757b32335..8dfa9db5d 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -1396,6 +1396,14 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l lp->region_size : seg->region_size , lp->pvh)) return_0; + if (lv_raid_has_integrity(lv)) { + struct integrity_settings *isettings = NULL; + if (!lv_get_raid_integrity_settings(lv, &isettings)) + return_0; + if (!lv_add_integrity_to_raid(lv, "external", isettings, lp->pvh)) + return_0; + } + log_print_unless_silent("Logical volume %s successfully converted.", display_lvname(lv)); @@ -1438,6 +1446,14 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l lp->region_size, lp->pvh)) return_0; + if (lv_raid_has_integrity(lv)) { + struct integrity_settings *isettings = NULL; + if (!lv_get_raid_integrity_settings(lv, &isettings)) + return_0; + if (!lv_add_integrity_to_raid(lv, "external", isettings, lp->pvh)) + return_0; + } + log_print_unless_silent("Logical volume %s successfully converted.", display_lvname(lv)); return 1; @@ -1459,6 +1475,14 @@ try_new_takeover_or_reshape: lp->region_size : seg->region_size , lp->pvh)) return_0; + if (lv_raid_has_integrity(lv)) { + struct integrity_settings *isettings = NULL; + if (!lv_get_raid_integrity_settings(lv, &isettings)) + return_0; + if (!lv_add_integrity_to_raid(lv, "external", isettings, lp->pvh)) + return_0; + } + log_print_unless_silent("Logical volume %s successfully converted.", display_lvname(lv)); return 1; @@ -5750,6 +5774,121 @@ int lvconvert_to_cache_with_cachevol_cmd(struct cmd_context *cmd, int argc, char return ret; } +static int _lvconvert_integrity_remove(struct cmd_context *cmd, + struct logical_volume *lv) +{ + struct volume_group *vg = lv->vg; + int ret; + + if (!lv_is_integrity(lv) && !lv_is_raid(lv)) { + log_error("LV does not have integrity."); + return 0; + } + + /* ensure it's not active elsewhere. */ + if (!lockd_lv(cmd, lv, "ex", 0)) + return_0; + + if (!archive(vg)) + return_0; + + if (lv_is_raid(lv)) + ret = lv_remove_integrity_from_raid(lv); + else + ret = lv_remove_integrity(lv); + if (!ret) + return 0; + + backup(vg); + + log_print_unless_silent("Logical volume %s has removed integrity.", display_lvname(lv)); + return 1; +} + +static int _lvconvert_integrity_add(struct cmd_context *cmd, + struct logical_volume *lv, + const char *meta_name, + struct integrity_settings *set) +{ + struct volume_group *vg = lv->vg; + struct dm_list *use_pvh; + int ret; + + /* ensure it's not active elsewhere. */ + if (!lockd_lv(cmd, lv, "ex", 0)) + return_0; + + if (cmd->position_argc > 1) { + /* First pos arg is required LV, remaining are optional PVs. */ + if (!(use_pvh = create_pv_list(cmd->mem, vg, cmd->position_argc - 1, cmd->position_argv + 1, 0))) + return_0; + } else + use_pvh = &vg->pvs; + + if (!archive(vg)) + return_0; + + if (lv_is_raid(lv)) + ret = lv_add_integrity_to_raid(lv, "external", set, use_pvh); + else + ret = lv_add_integrity(lv, "external", set, use_pvh); + if (!ret) + return 0; + + backup(vg); + + log_print_unless_silent("Logical volume %s has added integrity.", display_lvname(lv)); + return 1; +} + +static int _lvconvert_integrity_single(struct cmd_context *cmd, + struct logical_volume *lv, + struct processing_handle *handle) +{ + struct integrity_settings settings; + const char *meta_name = NULL; + const char *arg = NULL; + int ret = 0; + + memset(&settings, 0, sizeof(settings)); + + if (!get_integrity_options(cmd, &arg, &meta_name, &settings)) + return 0; + + if (*arg == 'y') + ret = _lvconvert_integrity_add(cmd, lv, meta_name, &settings); + + else if (*arg == 'n') + ret = _lvconvert_integrity_remove(cmd, lv); + + else + log_error("Invalid integrity option value."); + + if (!ret) + return ECMD_FAILED; + return ECMD_PROCESSED; +} + +int lvconvert_integrity_cmd(struct cmd_context *cmd, int argc, char **argv) +{ + struct processing_handle *handle; + int ret; + + if (!(handle = init_processing_handle(cmd, NULL))) { + log_error("Failed to initialize processing handle."); + return ECMD_FAILED; + } + + 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_integrity_single); + + destroy_processing_handle(cmd, handle); + + return ret; +} + /* * All lvconvert command defs have their own function, * so the generic function name is unused. |