summaryrefslogtreecommitdiff
path: root/tools/lvconvert.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lvconvert.c')
-rw-r--r--tools/lvconvert.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index d0d277bcd..e87bbd18b 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -5730,6 +5730,150 @@ 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;
+
+ if (!lv_is_integrity(lv) && !lv_is_raid(lv)) {
+ log_error("LV does not have integrity.");
+ return 0;
+ }
+
+ /* TODO: lift this restriction */
+ if (lv_info(cmd, lv, 1, NULL, 0, 0)) {
+ log_error("LV must be inactive to remove integrity.");
+ return 0;
+ }
+
+ if (!archive(vg))
+ return_0;
+
+ if (lv_is_integrity(lv)) {
+ if (!lv_remove_integrity(lv))
+ return_0;
+ } else if (lv_is_raid(lv)) {
+ if (!lv_remove_integrity_from_raid(lv))
+ return_0;
+ }
+
+ if (!vg_write(vg) || !vg_commit(vg))
+ 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 lv_activate_opts laopts = { 0 };
+ struct volume_group *vg = lv->vg;
+ struct lv_segment *seg;
+ struct dm_list *use_pvh;
+ int ret;
+
+ seg = first_seg(lv);
+
+ /* TODO: lift this restriction, if we can reload table to set recalculate */
+ if (lv_info(cmd, lv, 1, NULL, 0, 0)) {
+ log_error("LV must be inactive to add integrity.");
+ return 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 (seg_is_raid(seg))
+ ret = lv_add_integrity_to_raid(lv, "external", set, use_pvh);
+ else
+ ret = lv_add_integrity(lv, "external", meta_name, set, use_pvh);
+ if (!ret)
+ return 0;
+
+ backup(vg);
+
+ /*
+ * The LV needs to be activated to start the integrity metadata
+ * initialization.
+ */
+
+ laopts.integrity_recalculate = 1;
+
+ if (!activate_lv_opts(cmd, lv, &laopts)) {
+ log_error("Failed to activate LV %s.", display_lvname(lv));
+ log_error("The full LV should be zeroed to initialize integrity metadata.");
+ } else {
+ log_print("LV %s activated to initialize integrity.", display_lvname(lv));
+ }
+
+ 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 || !strcmp(arg, "external") || !strcmp(arg, "y"))
+ ret = _lvconvert_integrity_add(cmd, lv, meta_name, &settings);
+
+ else if (!strcmp(arg, "none") || !strcmp(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.