summaryrefslogtreecommitdiff
path: root/tools/lvconvert.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lvconvert.c')
-rw-r--r--tools/lvconvert.c139
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.