diff options
Diffstat (limited to 'tools/lvconvert.c')
-rw-r--r-- | tools/lvconvert.c | 130 |
1 files changed, 128 insertions, 2 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 68bd75cb5..2b289c232 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, isettings, lp->pvh, NULL)) + 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, isettings, lp->pvh, NULL)) + 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, isettings, lp->pvh, NULL)) + return_0; + } + log_print_unless_silent("Logical volume %s successfully converted.", display_lvname(lv)); return 1; @@ -1775,8 +1799,8 @@ static int _lvconvert_raid_types(struct cmd_context *cmd, struct logical_volume * If operations differ between striped and linear, split this case. */ if (segtype_is_striped(seg->segtype) || segtype_is_linear(seg->segtype)) { - ret = _convert_striped(cmd, lv, lp); - goto out; + if (!_convert_striped(cmd, lv, lp)) + goto_out; } /* @@ -5756,6 +5780,108 @@ 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 = 0; + + 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); + 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, + struct integrity_settings *set) +{ + struct volume_group *vg = lv->vg; + struct dm_list *use_pvh; + int ret = 0; + + /* 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, set, use_pvh, NULL); + 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; + int ret = 0; + + memset(&settings, 0, sizeof(settings)); + + if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &settings)) + return_ECMD_FAILED; + + if (arg_int_value(cmd, raidintegrity_ARG, 0)) + ret = _lvconvert_integrity_add(cmd, lv, &settings); + else + ret = _lvconvert_integrity_remove(cmd, lv); + + 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. |