summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2020-03-03 16:22:00 -0600
committerDavid Teigland <teigland@redhat.com>2020-03-04 13:48:26 -0600
commit450259a56e3620389c3a2c4ce2e5810e84e23983 (patch)
tree196589818fc494cb3f5cef91d296b57dcec42cbe
parent6e12ff95b2a6ac7d9ad08d911003326e9baae50f (diff)
downloadlvm2-dev-dct-integrity26.tar.gz
integrity changes and feature removalsdev-dct-integrity26
- remove support for handling integrity+linear - remove support for --integritysettings - rename --integrity to --raidintegrity - add --raidintegritymode bitmap|journal
-rw-r--r--lib/metadata/integrity_manip.c390
-rw-r--r--lib/metadata/lv_manip.c23
-rw-r--r--lib/metadata/metadata-exported.h7
-rw-r--r--lib/metadata/raid_manip.c22
-rw-r--r--test/shell/integrity-large.sh126
-rw-r--r--test/shell/integrity.sh135
-rw-r--r--tools/args.h13
-rw-r--r--tools/command-lines.in20
-rw-r--r--tools/lvconvert.c68
-rw-r--r--tools/lvcreate.c17
-rw-r--r--tools/toollib.c187
-rw-r--r--tools/tools.h5
12 files changed, 255 insertions, 758 deletions
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
index 062f6b954..4fdc87a4e 100644
--- a/lib/metadata/integrity_manip.c
+++ b/lib/metadata/integrity_manip.c
@@ -42,19 +42,6 @@ int lv_is_integrity_origin(const struct logical_volume *lv)
return 0;
}
-static struct logical_volume *_lv_integrity_from_origin(const struct logical_volume *lv)
-{
- struct seg_list *sl;
-
- dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
- if (!sl->seg || !sl->seg->lv || !sl->seg->origin)
- continue;
- if (lv_is_integrity(sl->seg->lv) && (sl->seg->origin == lv))
- return sl->seg->lv;
- }
- return NULL;
-}
-
/*
* Every 500M of data needs 4M of metadata.
* (From trial and error testing.)
@@ -122,70 +109,6 @@ static int _lv_create_integrity_metadata(struct cmd_context *cmd,
return 1;
}
-/*
- * This is used when extending integrity+linear (not raid).
- * lv_iorig has been extended, now extend the integrity layer
- * above it. This includes updating the sizes in the integrity
- * segment and extending the imeta LV.
- */
-int lv_extend_integrity_for_origin(struct logical_volume *lv_iorig, struct dm_list *pvh)
-{
- struct cmd_context *cmd = lv_iorig->vg->cmd;
- struct volume_group *vg = lv_iorig->vg;
- const struct segment_type *segtype;
- struct logical_volume *lv;
- struct logical_volume *lv_imeta;
- struct lv_segment *seg;
- struct dm_list *use_pvh = pvh;
- uint64_t lv_size_bytes, meta_bytes, meta_sectors, prev_meta_sectors;
- uint32_t meta_extents, prev_meta_extents;
-
- if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
- return_0;
-
- if (!(lv = _lv_integrity_from_origin(lv_iorig)))
- return_0;
-
- seg = first_seg(lv);
-
- lv_imeta = seg->integrity_meta_dev;
-
- if (!lv_imeta)
- return_0;
-
- /* new size in sectors */
- lv->size = lv_iorig->size;
- seg->integrity_data_sectors = lv_iorig->size;
- /* new size in extents */
- lv->le_count = lv_iorig->le_count;
- seg->len = lv_iorig->le_count;
- seg->area_len = lv_iorig->le_count;
-
- lv_size_bytes = lv_iorig->size * 512;
- meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes);
- meta_sectors = meta_bytes / 512;
- meta_extents = meta_sectors / vg->extent_size;
-
- prev_meta_sectors = lv_imeta->size;
- prev_meta_extents = prev_meta_sectors / vg->extent_size;
-
- if (meta_extents <= prev_meta_extents) {
- log_debug("extend not needed for imeta LV %s", lv_imeta->name);
- return 1;
- }
-
- /* FIXME: set use_pvh to the pvs in lv_imeta */
-
- if (!lv_extend(lv_imeta, segtype, 1, 0, 0, 0,
- meta_extents - prev_meta_extents,
- use_pvh, lv_imeta->alloc, 0)) {
- log_error("Failed to extend integrity metadata LV %s", lv_imeta->name);
- return 0;
- }
-
- return 1;
-}
-
int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh)
{
struct cmd_context *cmd = lv->vg->cmd;
@@ -336,75 +259,6 @@ int lv_remove_integrity_from_raid(struct logical_volume *lv)
return 1;
}
-int lv_remove_integrity(struct logical_volume *lv, struct logical_volume **keep_lv_imeta)
-{
- struct cmd_context *cmd = lv->vg->cmd;
- struct volume_group *vg = lv->vg;
- struct lv_segment *seg = first_seg(lv);
- struct logical_volume *lv_iorig;
- struct logical_volume *lv_imeta;
- int is_active = lv_is_active(lv);
-
- if (!seg_is_integrity(seg)) {
- log_error("LV %s segment is not integrity.", display_lvname(lv));
- return 0;
- }
-
- if (!seg->integrity_meta_dev) {
- log_error("Internal integrity cannot be removed.");
- return 0;
- }
-
- if (!(lv_imeta = seg->integrity_meta_dev)) {
- log_error("LV %s segment has no integrity metadata device.", display_lvname(lv));
- return 0;
- }
-
- if (!(lv_iorig = seg_lv(seg, 0))) {
- log_error("LV %s integrity segment has no origin", display_lvname(lv));
- return 0;
- }
-
- if (!remove_seg_from_segs_using_this_lv(seg->integrity_meta_dev, seg))
- return_0;
-
- lv->status &= ~INTEGRITY;
- seg->integrity_meta_dev = NULL;
-
- if (!remove_layer_from_lv(lv, lv_iorig))
- return_0;
-
- if (is_active) {
- /* vg_write(), suspend_lv(), vg_commit(), resume_lv() */
- if (!lv_update_and_reload(lv)) {
- log_error("Failed to update and reload LV after integrity remove.");
- return_0;
- }
-
- if (!deactivate_lv(cmd, lv_iorig))
- log_error("Failed to deactivate unused iorig LV %s.", lv_iorig->name);
-
- if (!deactivate_lv(cmd, lv_imeta))
- log_error("Failed to deactivate unused imeta LV %s.", lv_iorig->name);
- }
-
- lv_imeta->status &= ~INTEGRITY_METADATA;
- lv_set_visible(lv_imeta);
-
- if (!lv_remove(lv_iorig))
- log_error("Failed to remove unused iorig LV %s.", lv_iorig->name);
-
- if (keep_lv_imeta)
- *keep_lv_imeta = lv_imeta;
- else if (!lv_remove(lv_imeta))
- log_error("Failed to remove unused imeta LV %s.", lv_imeta->name);
-
- if (!vg_write(vg) || !vg_commit(vg))
- return_0;
-
- return 1;
-}
-
/*
* Add integrity to each raid image.
*
@@ -675,250 +529,6 @@ bad:
return 0;
}
-int lv_add_integrity(struct logical_volume *lv, struct integrity_settings *settings,
- struct dm_list *pvh)
-{
- struct lvcreate_params lp = { 0 };
- struct dm_list allocatable_pvs;
- struct cmd_context *cmd = lv->vg->cmd;
- struct volume_group *vg = lv->vg;
- struct integrity_settings *segset;
- struct logical_volume *lv_orig;
- struct logical_volume *meta_lv = NULL;
- const struct segment_type *segtype;
- struct dm_list *use_pvh = pvh;
- struct lv_segment *seg;
- uint64_t lv_size_sectors;
- int revert_meta_lv = 0;
- int is_active;
-
- lv_size_sectors = lv->size;
-
- is_active = lv_is_active(lv);
-
-#if 0
- /* If we allow a metadata LV to be specified. */
- if (meta_lv) {
- uint64_t meta_bytes, meta_sectors;
-
- meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_sectors * 512);
- meta_sectors = meta_bytes / 512;
-
- if (meta_lv->size < meta_sectors) {
- log_error("Integrity metadata needs %s, metadata LV is only %s.",
- display_size(cmd, meta_sectors), display_size(cmd, meta_lv->size));
- goto_bad;
- }
- }
-#endif
-
- dm_list_init(&allocatable_pvs);
-
- if (!get_pv_list_for_lv(cmd->mem, lv, &allocatable_pvs)) {
- log_error("Failed to build list of PVs for %s.", display_lvname(lv));
- goto_bad;
- }
-
- use_pvh = &allocatable_pvs;
-
- lp.lv_name = lv->name;
- lp.pvh = use_pvh;
- lp.extents = lv->size / vg->extent_size;
-
- if (!_lv_create_integrity_metadata(cmd, vg, &lp, &meta_lv))
- goto_bad;
-
- revert_meta_lv = 1;
-
- if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_INTEGRITY)))
- goto_bad;
-
- /*
- * "lv_orig" is a new LV with new id, but with the segments from "lv".
- * "lv" keeps the existing name and id, but gets a new integrity segment,
- * in place of the segments that were moved to lv_orig.
- */
-
- if (!(lv_orig = insert_layer_for_lv(cmd, lv, INTEGRITY, "_iorig")))
- goto_bad;
-
- seg = first_seg(lv);
- seg->segtype = segtype;
-
- lv->status |= INTEGRITY;
-
- memcpy(&seg->integrity_settings, settings, sizeof(struct integrity_settings));
- segset = &seg->integrity_settings;
-
- if (!segset->mode[0])
- segset->mode[0] = DEFAULT_MODE;
-
- if (!segset->tag_size)
- segset->tag_size = DEFAULT_TAG_SIZE;
-
- if (!segset->internal_hash)
- segset->internal_hash = DEFAULT_INTERNAL_HASH;
-
- /*
- * When not using a metadata LV, dm-integrity needs to tell us what the
- * usable size of the LV is, which is the dev size minus the integrity
- * overhead. To find that, we need to do a special, temporary activation
- * of the new LV, specifying a dm dev size of 1, then check the dm dev
- * status field provided_data_sectors, which is the actual size of the
- * LV. We need to include provided_data_sectors in the metadata for the
- * new LV, and use this as the dm dev size for normal LV activation.
- *
- * When using a metadata LV, the dm dev size is the size of the data
- * device. The necessary size of the metadata LV for the given data
- * device needs to be estimated.
- */
-
- if (meta_lv) {
- struct wipe_params wipe = { .do_zero = 1, .zero_sectors = 8 };
-
- if (!sync_local_dev_names(cmd)) {
- log_error("Failed to sync local devices.");
- goto_bad;
- }
-
- log_verbose("Zeroing LV for integrity metadata");
-
- if (!lv_is_active(meta_lv)) {
- if (!activate_lv(cmd, meta_lv)) {
- log_error("Failed to activate LV %s to zero", display_lvname(meta_lv));
- goto_bad;
- }
- }
-
- if (!wipe_lv(meta_lv, wipe)) {
- log_error("Failed to zero LV for integrity metadata %s", display_lvname(meta_lv));
- if (!deactivate_lv(cmd, meta_lv))
- log_error("Failed to deactivate LV %s after zero", display_lvname(meta_lv));
- goto_bad;
- }
-
- if (!deactivate_lv(cmd, meta_lv)) {
- log_error("Failed to deactivate LV %s after zero", display_lvname(meta_lv));
- goto_bad;
- }
-
- meta_lv->status |= INTEGRITY_METADATA;
- seg->integrity_data_sectors = lv_size_sectors;
- seg->integrity_recalculate = 1;
- seg->integrity_meta_dev = meta_lv;
- lv_set_hidden(meta_lv);
- } else {
- log_error("Missing integrity metadata LV.");
- goto bad;
-#if 0
- /* dm-integrity wants temp/fake size of 1 to report usable size */
- seg->integrity_data_sectors = 1;
- seg->integrity_recalculate = 1;
-
- /* write-commit allows activating the LV to get data_sectors */
- if (!vg_write(vg) || !vg_commit(vg)) {
- log_error("Preliminary internal integrity write commit error");
- goto_bad;
- }
-
- lv->status |= LV_TEMPORARY;
- lv->status |= LV_NOSCAN;
-
- log_debug("Activating temporary integrity LV to get data sectors.");
-
- if (!activate_lv(cmd, lv)) {
- log_error("Failed to activate temporary integrity.");
- goto_bad;
- }
-
- if (!_get_provided_data_sectors(lv, &seg->integrity_data_sectors)) {
- log_error("Failed to get data sectors from dm-integrity");
- ret = 0;
- } else {
- log_debug("Found integrity provided_data_sectors %llu", (unsigned long long)seg->integrity_data_sectors);
- ret = 1;
- }
-
- if (!seg->integrity_data_sectors) {
- log_error("LV size too small to include metadata.");
- ret = 0;
- }
-
- if (!deactivate_lv(cmd, lv)) {
- log_error("Failed to deactivate temporary integrity.");
- ret = 0;
- }
-
- lv->status &= ~LV_NOSCAN;
- lv->status &= ~LV_TEMPORARY;
-
- if (!ret)
- goto_bad;
-#endif
- }
-
- if (is_active) {
- log_debug("Writing VG and updating LV with new integrity LV %s", lv->name);
-
- /* vg_write(), suspend_lv(), vg_commit(), resume_lv() */
- if (!lv_update_and_reload(lv)) {
- log_error("LV update and reload failed");
- goto_bad;
- }
- revert_meta_lv = 0;
-
- } else {
- log_debug("Writing VG with new integrity LV %s", lv->name);
-
- if (!vg_write(vg) || !vg_commit(vg))
- goto_bad;
-
- revert_meta_lv = 0;
-
- /*
- * This first activation includes "recalculate" which starts the
- * kernel's recalculating (initialization) process.
- */
-
- log_debug("Activating to start integrity initialization for LV %s", lv->name);
-
- if (!activate_lv(cmd, lv)) {
- log_error("Failed to activate integrity LV to initialize.");
- goto_bad;
- }
- }
-
- /*
- * Now that the device is being initialized, update the VG to clear
- * integrity_recalculate so that subsequent activations will not
- * include "recalculate" and restart initialization.
- *
- * If command fails here, before clearing integrity_recalculate from
- * the metadata, then the next activation will clear this
- * (see lv_clear_integrity_recalculate_metadata).
- */
-
- log_debug("Writing VG with initialized integrity LV %s", lv->name);
-
- seg->integrity_recalculate = 0;
-
- if (!vg_write(vg) || !vg_commit(vg))
- goto_bad;
-
- return 1;
-
- bad:
- log_error("Failed to add integrity.");
-
- if (revert_meta_lv) {
- log_debug("Removing meta LV %s", meta_lv->name);
- if (!lv_remove(meta_lv) || !vg_write(vg) || !vg_commit(vg))
- log_error("New integrity metadata LV may require manual removal: %s", display_lvname(meta_lv));
- }
-
- return 0;
-}
-
/*
* This should rarely if ever be used. A command that adds integrity
* to an LV will activate and then clear the flag. If it fails before
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index fc97526d3..d1d7313ea 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4498,18 +4498,6 @@ int lv_extend(struct logical_volume *lv,
}
out:
- /*
- * When an integrity+linear LV is being extended, the lv_iorig (origin)
- * is passed into lv_extend() as 'lv'. lv_is_integrity_origin checks
- * if this lv has an integrity layer above it, and if so, calls
- * lv_extend_integrity_for_origin to change the sizes in the integrity
- * layer to match the newly extended origin, and to extend the imeta LV.
- */
- if (r && lv_is_integrity_origin(lv)) {
- if (!lv_extend_integrity_for_origin(lv, allocatable_pvs))
- r = 0;
- }
-
alloc_destroy(ah);
return r;
}
@@ -8336,16 +8324,11 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
goto out;
}
- if (seg_is_integrity(lp) || (seg_is_raid(lp) && lp->integrity_arg)) {
+ if (seg_is_raid(lp) && lp->raidintegrity) {
log_debug("Adding integrity to new LV");
- if (seg_is_raid(lp)) {
- if (!lv_add_integrity_to_raid(lv, &lp->integrity_settings, lp->pvh, NULL))
- goto revert_new_lv;
- } else {
- if (!lv_add_integrity(lv, &lp->integrity_settings, lp->pvh))
- goto revert_new_lv;
- }
+ if (!lv_add_integrity_to_raid(lv, &lp->integrity_settings, lp->pvh, NULL))
+ goto revert_new_lv;
backup(vg);
}
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d96eec101..52bc77673 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1003,8 +1003,8 @@ struct lvcreate_params {
alloc_policy_t alloc; /* all */
struct dm_vdo_target_params vdo_params; /* vdo */
- const char *integrity_arg;
- const char *integrity_meta_name;
+ int raidintegrity;
+ const char *raidintegritymode;
struct integrity_settings integrity_settings;
struct dm_list tags; /* all */
@@ -1406,16 +1406,13 @@ struct dm_list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int
char **argv, int allocatable_only);
struct dm_list *clone_pv_list(struct dm_pool *mem, struct dm_list *pvsl);
-int lv_add_integrity(struct logical_volume *lv, struct integrity_settings *settings, struct dm_list *pvh);
int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_settings *settings, struct dm_list *pvh,
struct logical_volume *lv_imeta_0);
-int lv_remove_integrity(struct logical_volume *lv, struct logical_volume **keep_lv_imeta);
int lv_remove_integrity_from_raid(struct logical_volume *lv);
void lv_clear_integrity_recalculate_metadata(struct logical_volume *lv);
int lv_has_integrity_recalculate_metadata(struct logical_volume *lv);
int lv_raid_has_integrity(struct logical_volume *lv);
int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh);
-int lv_extend_integrity_for_origin(struct logical_volume *lv_iorig, struct dm_list *pvh);
int lv_get_raid_integrity_settings(struct logical_volume *lv, struct integrity_settings **isettings);
#endif
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index c986ea9e0..88b833ab3 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -3119,6 +3119,11 @@ static int _raid_remove_images(struct logical_volume *lv, int yes,
/* Convert to linear? */
if (new_count == 1) {
+ if (seg_is_integrity(first_seg(lv))) {
+ log_error("RAID checksums must be disabled before converting to linear.");
+ return 0;
+ }
+
if (!yes && yes_no_prompt("Are you sure you want to convert %s LV %s to type %s losing all resilience? [y/n]: ",
lvseg_name(first_seg(lv)), display_lvname(lv), SEG_TYPE_NAME_LINEAR) == 'n') {
log_error("Logical volume %s NOT converted to \"%s\".",
@@ -3132,18 +3137,6 @@ static int _raid_remove_images(struct logical_volume *lv, int yes,
}
lv->status &= ~(LV_NOTSYNCED | LV_WRITEMOSTLY);
first_seg(lv)->writebehind = 0;
-
- if (seg_is_integrity(first_seg(lv))) {
- char imeta_name[NAME_LEN];
- char *imeta_name_dup;
- struct lv_segment *iseg = first_seg(lv);
- struct logical_volume *lv_imeta = iseg->integrity_meta_dev;
-
- if (dm_snprintf(imeta_name, sizeof(imeta_name), "%s_imeta", lv->name) > 0) {
- if ((imeta_name_dup = dm_pool_strdup(lv->vg->vgmem, imeta_name)))
- lv_imeta->name = imeta_name_dup;
- }
- }
}
if (!commit)
@@ -3277,6 +3270,11 @@ int lv_raid_split(struct logical_volume *lv, int yes, const char *split_name,
return 0;
}
+ if (lv_raid_has_integrity(lv)) {
+ log_error("RAID checksums must be disabled before splitting.");
+ return 0;
+ }
+
if ((old_count - new_count) != 1) {
log_error("Unable to split more than one image from %s.",
display_lvname(lv));
diff --git a/test/shell/integrity-large.sh b/test/shell/integrity-large.sh
new file mode 100644
index 000000000..abae83f74
--- /dev/null
+++ b/test/shell/integrity-large.sh
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Test writecache usage
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+# aux have_integrity 1 0 0 || skip
+which mkfs.xfs || skip
+
+mnt="mnt"
+mkdir -p $mnt
+
+# raid1 LV needs to be extended to 512MB to test imeta being exended
+aux prepare_devs 2 600
+
+for i in `seq 1 16384`; do echo -n "A" >> fileA; done
+for i in `seq 1 16384`; do echo -n "B" >> fileB; done
+for i in `seq 1 16384`; do echo -n "C" >> fileC; done
+
+# generate random data
+dd if=/dev/urandom of=randA bs=512K count=2
+dd if=/dev/urandom of=randB bs=512K count=3
+dd if=/dev/urandom of=randC bs=512K count=4
+
+_prepare_vg() {
+ vgcreate $SHARED $vg "$dev1" "$dev2"
+ pvs
+}
+
+_add_data_to_lv() {
+ mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" $mnt
+
+ # add original data
+ cp randA $mnt
+ cp randB $mnt
+ cp randC $mnt
+ mkdir $mnt/1
+ cp fileA $mnt/1
+ cp fileB $mnt/1
+ cp fileC $mnt/1
+ mkdir $mnt/2
+ cp fileA $mnt/2
+ cp fileB $mnt/2
+ cp fileC $mnt/2
+
+ umount $mnt
+}
+
+_verify_data_on_lv() {
+ mount "$DM_DEV_DIR/$vg/$lv1" $mnt
+
+ diff randA $mnt/randA
+ diff randB $mnt/randB
+ diff randC $mnt/randC
+ diff fileA $mnt/1/fileA
+ diff fileB $mnt/1/fileB
+ diff fileC $mnt/1/fileC
+ diff fileA $mnt/2/fileA
+ diff fileB $mnt/2/fileB
+ diff fileC $mnt/2/fileC
+
+ umount $mnt
+}
+
+_sync_percent() {
+ local checklv=$1
+ get lv_field "$checklv" sync_percent | cut -d. -f1
+}
+
+_wait_recalc() {
+ local checklv=$1
+
+ for i in $(seq 1 10) ; do
+ sync=$(_sync_percent "$checklv")
+ echo "sync_percent is $sync"
+
+ if test "$sync" = "100"; then
+ return
+ fi
+
+ sleep 1
+ done
+
+ echo "timeout waiting for recalc"
+ return 1
+}
+
+# lvextend to 512MB is needed for the imeta LV to
+# be extended from 4MB to 8MB.
+
+_prepare_vg
+lvcreate --type raid1 -m1 -n $lv1 -l 8 $vg
+lvchange -an $vg/$lv1
+lvchange -ay $vg/$lv1
+_add_data_to_lv
+lvconvert --raidintegrity y $vg/$lv1
+_wait_recalc $vg/$lv1
+lvs -a -o+devices $vg
+_verify_data_on_lv
+lvchange -an $vg/$lv1
+lvextend -L 512M $vg/$lv1
+lvs -a -o+devices $vg
+lvchange -ay $vg/$lv1
+_verify_data_on_lv
+_wait_recalc $vg/$lv1
+lvs -a -o+devices $vg
+check lv_field $vg/${lv1}_rimage_0_imeta size "8.00m"
+check lv_field $vg/${lv1}_rimage_1_imeta size "8.00m"
+lvchange -an $vg/$lv1
+lvremove $vg/$lv1
+vgremove -ff $vg
+
diff --git a/test/shell/integrity.sh b/test/shell/integrity.sh
index 66a82a7d4..eca7a616f 100644
--- a/test/shell/integrity.sh
+++ b/test/shell/integrity.sh
@@ -21,7 +21,8 @@ which mkfs.xfs || skip
mnt="mnt"
mkdir -p $mnt
-aux prepare_devs 5 128
+
+aux prepare_devs 5 64
for i in `seq 1 16384`; do echo -n "A" >> fileA; done
for i in `seq 1 16384`; do echo -n "B" >> fileB; done
@@ -41,6 +42,7 @@ _prepare_vg() {
dd if=/dev/zero of="$dev4" || true
dd if=/dev/zero of="$dev5" || true
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
+ pvs
}
_test_fs_with_error() {
@@ -191,75 +193,55 @@ _wait_recalc() {
}
_prepare_vg
-lvcreate --integrity y -n $lv1 -l 8 $vg "$dev1"
-_test_fs_with_error
-lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
-lvremove $vg/$lv1
-vgremove -ff $vg
-
-_prepare_vg
-lvcreate --type raid1 -m1 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg
_test_fs_with_raid
lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
_prepare_vg
-lvcreate --type raid1 -m2 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid1 -m2 --raidintegrity y -n $lv1 -l 8 $vg
_test_fs_with_raid
lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
_prepare_vg
-lvcreate --type raid4 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid4 --raidintegrity y -n $lv1 -l 8 $vg
_test_fs_with_raid
lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
_prepare_vg
-lvcreate --type raid5 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid5 --raidintegrity y -n $lv1 -l 8 $vg
_test_fs_with_raid
lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
_prepare_vg
-lvcreate --type raid6 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid6 --raidintegrity y -n $lv1 -l 8 $vg
_test_fs_with_raid
lvchange -an $vg/$lv1
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
# Test removing integrity from an active LV
_prepare_vg
-lvcreate --integrity y -n $lv1 -l 8 $vg
-_wait_recalc $vg/$lv1
-lvchange -an $vg/$lv1
-lvchange -ay $vg/$lv1
-_add_data_to_lv
-lvconvert --integrity n $vg/$lv1
-_verify_data_on_lv
-lvchange -an $vg/$lv1
-lvremove $vg/$lv1
-vgremove -ff $vg
-
-_prepare_vg
-lvcreate --type raid1 -m1 --integrity y -n $lv1 -l 8 $vg
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -l 8 $vg
_wait_recalc $vg/${lv1}_rimage_0
_wait_recalc $vg/${lv1}_rimage_1
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
_add_data_to_lv
-lvconvert --integrity n $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
_verify_data_on_lv
lvchange -an $vg/$lv1
lvremove $vg/$lv1
@@ -268,92 +250,107 @@ vgremove -ff $vg
# Test adding integrity to an active LV
_prepare_vg
-lvcreate -n $lv1 -l 8 $vg
+lvcreate --type raid1 -m1 -n $lv1 -l 8 $vg
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
_add_data_to_lv
-lvconvert --integrity y $vg/$lv1
-_wait_recalc $vg/$lv1
+lvconvert --raidintegrity y $vg/$lv1
+_wait_recalc $vg/${lv1}_rimage_0
+_wait_recalc $vg/${lv1}_rimage_1
_verify_data_on_lv
lvchange -an $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
+# Test lvextend
+
_prepare_vg
lvcreate --type raid1 -m1 -n $lv1 -l 8 $vg
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
_add_data_to_lv
-lvconvert --integrity y $vg/$lv1
+lvconvert --raidintegrity y $vg/$lv1
_wait_recalc $vg/${lv1}_rimage_0
_wait_recalc $vg/${lv1}_rimage_1
+lvs -a -o+devices $vg
_verify_data_on_lv
lvchange -an $vg/$lv1
+lvextend -l 16 $vg/$lv1
+lvchange -ay $vg/$lv1
+_verify_data_on_lv
+_wait_recalc $vg/${lv1}_rimage_0
+_wait_recalc $vg/${lv1}_rimage_1
+lvs -a -o+devices $vg
+lvchange -an $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
-# Test lvextend
+# Repeat many of the tests above using journal mode
_prepare_vg
-lvcreate -n $lv1 -l 8 $vg
+lvcreate --type raid1 -m1 --raidintegrity y --raidintegritymode journal -n $lv1 -l 8 $vg
+_test_fs_with_raid
lvchange -an $vg/$lv1
-lvchange -ay $vg/$lv1
-_add_data_to_lv
-lvconvert --integrity y $vg/$lv1
-_wait_recalc $vg/$lv1
-lvs -a $vg
-_verify_data_on_lv
+lvconvert --raidintegrity n $vg/$lv1
+lvremove $vg/$lv1
+vgremove -ff $vg
+
+_prepare_vg
+lvcreate --type raid6 --raidintegrity y --raidintegritymode journal -n $lv1 -l 8 $vg
+_test_fs_with_raid
+lvchange -an $vg/$lv1
+lvconvert --raidintegrity n $vg/$lv1
+lvremove $vg/$lv1
+vgremove -ff $vg
+
+# remove from active lv
+_prepare_vg
+lvcreate --type raid1 -m1 --raidintegrity y --raidintegritymode journal -n $lv1 -l 8 $vg
+_wait_recalc $vg/${lv1}_rimage_0
+_wait_recalc $vg/${lv1}_rimage_1
lvchange -an $vg/$lv1
-lvextend -l 16 $vg/$lv1
lvchange -ay $vg/$lv1
+_add_data_to_lv
+lvconvert --raidintegrity n $vg/$lv1
_verify_data_on_lv
-_wait_recalc $vg/$lv1
-lvs -a $vg
lvchange -an $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
+# add to active lv
_prepare_vg
-lvcreate --type raid1 -m1 -n $lv1 -l 8 $vg
+lvcreate --type raid1 --raidintegritymode journal -m1 -n $lv1 -l 8 $vg
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
_add_data_to_lv
-lvconvert --integrity y $vg/$lv1
+lvconvert --raidintegrity y $vg/$lv1
_wait_recalc $vg/${lv1}_rimage_0
_wait_recalc $vg/${lv1}_rimage_1
-lvs -a $vg
_verify_data_on_lv
lvchange -an $vg/$lv1
-lvextend -l 16 $vg/$lv1
-lvchange -ay $vg/$lv1
-_verify_data_on_lv
-_wait_recalc $vg/${lv1}_rimage_0
-_wait_recalc $vg/${lv1}_rimage_1
-lvs -a $vg
-lvchange -an $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
-# lvextend to 512MB is needed for the imeta LV to
-# be extended from 4MB to 8MB.
-
+# lvextend
_prepare_vg
-lvcreate -n $lv1 -l 8 $vg
+lvcreate --type raid1 --raidintegritymode journal -m1 -n $lv1 -l 8 $vg
lvchange -an $vg/$lv1
lvchange -ay $vg/$lv1
_add_data_to_lv
-lvconvert --integrity y $vg/$lv1
-_wait_recalc $vg/$lv1
-lvs -a $vg
+lvconvert --raidintegrity y $vg/$lv1
+_wait_recalc $vg/${lv1}_rimage_0
+_wait_recalc $vg/${lv1}_rimage_1
+lvs -a -o+devices $vg
_verify_data_on_lv
lvchange -an $vg/$lv1
-lvextend -L 512M $vg/$lv1
+lvextend -l 16 $vg/$lv1
lvchange -ay $vg/$lv1
_verify_data_on_lv
-_wait_recalc $vg/$lv1
-lvs -a $vg
-check lv_field $vg/${lv1}_imeta size "8.00m"
+_wait_recalc $vg/${lv1}_rimage_0
+_wait_recalc $vg/${lv1}_rimage_1
+lvs -a -o+devices $vg
lvchange -an $vg/$lv1
lvremove $vg/$lv1
vgremove -ff $vg
+
diff --git a/tools/args.h b/tools/args.h
index 4a68b8a0b..1d652b557 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -274,12 +274,6 @@ arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0,
"and \\fBdiff\\fP types include unsupported settings in their output by default,\n"
"all the other types ignore unsupported settings.\n")
-arg(integrity_ARG, '\0', "integrity", bool_VAL, 0, 0,
- "Enable or disable integrity metadata for an LV.\n")
-
-arg(integritysettings_ARG, '\0', "integritysettings", string_VAL, ARG_GROUPABLE, 0,
- "Set dm-integrity parameters.\n")
-
arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0,
"By default the PV is labelled with an LVM2 identifier in its second\n"
"sector (sector 1). This lets you use a different sector near the\n"
@@ -518,6 +512,13 @@ arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", pvmetadatacopies_VAL, 0, 0,
"This may be useful in VGs containing many PVs (this places limitations\n"
"on the ability to use vgsplit later.)\n")
+arg(raidintegrity_ARG, '\0', "raidintegrity", bool_VAL, 0, 0,
+ "Enable or disable data integrity checksums for raid images.\n")
+
+arg(raidintegritymode_ARG, '\0', "raidintegritymode", string_VAL, 0, 0,
+ "Use a bitmap (default) or journal for keeping integrity checksums consistent\n"
+ "in case of a crash.\n")
+
arg(readonly_ARG, '\0', "readonly", 0, 0, 0,
"Run the command in a special read-only mode which will read on-disk\n"
"metadata without needing to take any locks. This can be used to peek\n"
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 0ef0e911e..dc86939ab 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -757,11 +757,11 @@ FLAGS: SECONDARY_SYNTAX
---
-lvconvert --integrity Bool LV_raid_integrity_linear_striped
-OO: OO_LVCONVERT, --integritysettings String
+lvconvert --raidintegrity Bool LV_raid
+OO: --raidintegritymode String, OO_LVCONVERT
OP: PV ...
ID: lvconvert_integrity
-DESC: Add or remove integrity to an LV.
+DESC: Add or remove data integrity checksums to raid images.
---
@@ -879,7 +879,7 @@ DESC: Create a raid1 or mirror LV (infers --type raid1|mirror).
lvcreate --type raid --size SizeMB VG
OO: --mirrors PNumber, --stripes Number, --stripesize SizeKB,
--regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
---integrity Bool, --integritysettings String, OO_LVCREATE
+--raidintegrity Bool, --raidintegritymode String, OO_LVCREATE
OP: PV ...
ID: lvcreate_raid_any
DESC: Create a raid LV (a specific raid level must be used, e.g. raid1).
@@ -1276,18 +1276,6 @@ DESC: to type cache after creating a new cache pool LV to use
DESC: (use lvconvert).
FLAGS: SECONDARY_SYNTAX
-lvcreate --type integrity --size SizeMB VG
-OO: --integrity Bool, --integritysettings String, OO_LVCREATE
-OP: PV ...
-ID: lvcreate_integrity
-DESC: Create a linear LV with integrity.
-
-lvcreate --integrity Bool --size SizeMB VG
-OO: --type integrity, --integritysettings String, OO_LVCREATE
-OP: PV ...
-ID: lvcreate_integrity
-DESC: Create a linear LV with integrity (infers --type integrity).
-
---
lvdisplay
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index b503bdf7a..2b289c232 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -85,8 +85,6 @@ struct lvconvert_params {
struct dm_list idls;
const char *origin_name;
-
- struct logical_volume *prev_lv_imeta;
};
struct convert_poll_id_list {
@@ -1738,36 +1736,12 @@ static int _lvconvert_raid_types(struct cmd_context *cmd, struct logical_volume
struct lvconvert_params *lp)
{
struct lv_segment *seg = first_seg(lv);
- struct integrity_settings isettings;
- int add_integrity = 0;
int ret = 0;
/* If LV is inactive here, ensure it's not active elsewhere. */
if (!lockd_lv(cmd, lv, "ex", 0))
return_ECMD_FAILED;
- /*
- * Converting integrity+linear to raid+integrity. The imeta
- * used for the linear LV can be used for that same linear LV
- * in its new position as a raid image.
- *
- * Remove the top integrity layer (saving the detached imeta LV),
- * do the raid conversion on the linear LV, which makes the new
- * top LV a raid LV. When integrity is added to the raid images,
- * use the saved imeta LV and reattach it to the same linear LV
- * that is now a raid image.
- */
- if (lv_is_integrity(lv)) {
- struct lv_segment *iseg = first_seg(lv);
-
- memcpy(&isettings, &iseg->integrity_settings, sizeof(isettings));
- add_integrity = 1;
-
- if (!lv_remove_integrity(lv, &lp->prev_lv_imeta))
- goto_out;
- seg = first_seg(lv);
- }
-
/* Set up segtype either from type_str or else to match the existing one. */
if (!*lp->type_str)
lp->segtype = seg->segtype;
@@ -1827,11 +1801,6 @@ static int _lvconvert_raid_types(struct cmd_context *cmd, struct logical_volume
if (segtype_is_striped(seg->segtype) || segtype_is_linear(seg->segtype)) {
if (!_convert_striped(cmd, lv, lp))
goto_out;
-
- if (add_integrity) {
- if (!lv_add_integrity_to_raid(lv, &isettings, lp->pvh, lp->prev_lv_imeta))
- goto_out;
- }
}
/*
@@ -5811,11 +5780,10 @@ 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)
+static int _lvconvert_integrity_remove(struct cmd_context *cmd, struct logical_volume *lv)
{
struct volume_group *vg = lv->vg;
- int ret;
+ int ret = 0;
if (!lv_is_integrity(lv) && !lv_is_raid(lv)) {
log_error("LV does not have integrity.");
@@ -5831,10 +5799,8 @@ static int _lvconvert_integrity_remove(struct cmd_context *cmd,
if (lv_is_raid(lv))
ret = lv_remove_integrity_from_raid(lv);
- else
- ret = lv_remove_integrity(lv, NULL);
if (!ret)
- return 0;
+ return_0;
backup(vg);
@@ -5842,14 +5808,12 @@ static int _lvconvert_integrity_remove(struct cmd_context *cmd,
return 1;
}
-static int _lvconvert_integrity_add(struct cmd_context *cmd,
- struct logical_volume *lv,
- const char *meta_name,
- struct integrity_settings *set)
+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;
+ int ret = 0;
/* ensure it's not active elsewhere. */
if (!lockd_lv(cmd, lv, "ex", 0))
@@ -5867,10 +5831,8 @@ static int _lvconvert_integrity_add(struct cmd_context *cmd,
if (lv_is_raid(lv))
ret = lv_add_integrity_to_raid(lv, set, use_pvh, NULL);
- else
- ret = lv_add_integrity(lv, set, use_pvh);
if (!ret)
- return 0;
+ return_0;
backup(vg);
@@ -5883,23 +5845,17 @@ static int _lvconvert_integrity_single(struct cmd_context *cmd,
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);
+ 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
- log_error("Invalid integrity option value.");
+ ret = _lvconvert_integrity_remove(cmd, lv);
if (!ret)
return ECMD_FAILED;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index be72b2567..261624ae3 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -794,8 +794,6 @@ static int _lvcreate_params(struct cmd_context *cmd,
mirror_default_cfg = (arg_uint_value(cmd, stripes_ARG, 1) > 1)
? global_raid10_segtype_default_CFG : global_mirror_segtype_default_CFG;
segtype_str = find_config_tree_str(cmd, mirror_default_cfg, NULL);
- } else if (arg_is_set(cmd, integrity_ARG)) {
- segtype_str = SEG_TYPE_NAME_INTEGRITY;
} else
segtype_str = SEG_TYPE_NAME_STRIPED;
@@ -830,8 +828,6 @@ static int _lvcreate_params(struct cmd_context *cmd,
readahead_ARG,\
setactivationskip_ARG,\
test_ARG,\
- integrity_ARG,\
- integritysettings_ARG,\
type_ARG
#define CACHE_POOL_ARGS \
@@ -862,7 +858,9 @@ static int _lvcreate_params(struct cmd_context *cmd,
maxrecoveryrate_ARG,\
minrecoveryrate_ARG,\
raidmaxrecoveryrate_ARG,\
- raidminrecoveryrate_ARG
+ raidminrecoveryrate_ARG, \
+ raidintegrity_ARG, \
+ raidintegritymode_ARG
#define SIZE_ARGS \
extents_ARG,\
@@ -1231,9 +1229,12 @@ static int _lvcreate_params(struct cmd_context *cmd,
}
}
- if (seg_is_integrity(lp) || seg_is_raid(lp)) {
- if (!get_integrity_options(cmd, &lp->integrity_arg, &lp->integrity_meta_name, &lp->integrity_settings))
- return 0;
+ if (seg_is_raid(lp)) {
+ lp->raidintegrity = arg_int_value(cmd, raidintegrity_ARG, 0);
+ if (arg_is_set(cmd, raidintegritymode_ARG)) {
+ if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &lp->integrity_settings))
+ return_0;
+ }
}
lcp->pv_count = argc;
diff --git a/tools/toollib.c b/tools/toollib.c
index 4423276bc..23cd8e22f 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -718,6 +718,20 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
return 1;
}
+int integrity_mode_set(const char *mode, struct integrity_settings *settings)
+{
+ if (!mode || !strcmp(mode, "bitmap") || !strcmp(mode, "B"))
+ settings->mode[0] = 'B';
+ else if (!strcmp(mode, "journal") || !strcmp(mode, "J"))
+ settings->mode[0] = 'J';
+ else {
+ /* FIXME: the kernel has other modes, should we allow any of those? */
+ log_error("Invalid raid integrity mode (use \"bitmap\" or \"journal\")");
+ return 0;
+ }
+ return 1;
+}
+
/* Shared code for changing activation state for vgchange/lvchange */
int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
activation_change_t activate)
@@ -1171,179 +1185,6 @@ out:
}
-static int _get_one_integrity_setting(struct cmd_context *cmd, struct integrity_settings *settings,
- char *key, char *val)
-{
- if (!strncmp(key, "mode", strlen("mode"))) {
- if (*val == 'D')
- settings->mode[0] = 'D';
- else if (*val == 'J')
- settings->mode[0] = 'J';
- else if (*val == 'B')
- settings->mode[0] = 'B';
- else if (*val == 'R')
- settings->mode[0] = 'R';
- else
- goto_bad;
- /* lvm assigns a default if the user doesn't. */
- return 1;
- }
-
- if (!strncmp(key, "tag_size", strlen("tag_size"))) {
- if (sscanf(val, "%u", &settings->tag_size) != 1)
- goto_bad;
- /* lvm assigns a default if the user doesn't. */
- return 1;
- }
-
- if (!strncmp(key, "internal_hash", strlen("internal_hash"))) {
- if (!(settings->internal_hash = dm_pool_strdup(cmd->mem, val)))
- goto_bad;
- /* lvm assigns a default if the user doesn't. */
- return 1;
- }
-
- /*
- * For the following settings, lvm does not set a default value if the
- * user does not specify their own value, and lets dm-integrity use its
- * own default.
- */
-
- if (!strncmp(key, "journal_sectors", strlen("journal_sectors"))) {
- if (sscanf(val, "%u", &settings->journal_sectors) != 1)
- goto_bad;
- settings->journal_sectors_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "interleave_sectors", strlen("interleave_sectors"))) {
- if (sscanf(val, "%u", &settings->interleave_sectors) != 1)
- goto_bad;
- settings->interleave_sectors_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "buffer_sectors", strlen("buffer_sectors"))) {
- if (sscanf(val, "%u", &settings->buffer_sectors) != 1)
- goto_bad;
- settings->buffer_sectors_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "journal_watermark", strlen("journal_watermark"))) {
- if (sscanf(val, "%u", &settings->journal_watermark) != 1)
- goto_bad;
- settings->journal_watermark_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "commit_time", strlen("commit_time"))) {
- if (sscanf(val, "%u", &settings->commit_time) != 1)
- goto_bad;
- settings->commit_time_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "block_size", strlen("block_size"))) {
- if (sscanf(val, "%u", &settings->block_size) != 1)
- goto_bad;
- settings->block_size_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "bitmap_flush_interval", strlen("bitmap_flush_interval"))) {
- if (sscanf(val, "%u", &settings->bitmap_flush_interval) != 1)
- goto_bad;
- settings->bitmap_flush_interval_set = 1;
- return 1;
- }
-
- if (!strncmp(key, "sectors_per_bit", strlen("sectors_per_bit"))) {
- if (sscanf(val, "%llu", (unsigned long long *)&settings->sectors_per_bit) != 1)
- goto_bad;
- settings->sectors_per_bit_set = 1;
- return 1;
- }
-
- log_error("Unknown setting: %s", key);
- return 0;
-
- bad:
- log_error("Invalid setting: %s", key);
- return 0;
-}
-
-static int _get_integrity_settings(struct cmd_context *cmd, struct integrity_settings *settings)
-{
- struct arg_value_group_list *group;
- const char *str;
- char key[64];
- char val[64];
- int num;
- int pos;
-
- /*
- * "grouped" means that multiple --integritysettings options can be used.
- * Each option is also allowed to contain multiple key = val pairs.
- */
-
- dm_list_iterate_items(group, &cmd->arg_value_groups) {
- if (!grouped_arg_is_set(group->arg_values, integritysettings_ARG))
- continue;
-
- if (!(str = grouped_arg_str_value(group->arg_values, integritysettings_ARG, NULL)))
- break;
-
- pos = 0;
-
- while (pos < strlen(str)) {
- /* scan for "key1=val1 key2 = val2 key3= val3" */
-
- memset(key, 0, sizeof(key));
- memset(val, 0, sizeof(val));
-
- if (sscanf(str + pos, " %63[^=]=%63s %n", key, val, &num) != 2) {
- log_error("Invalid setting at: %s", str+pos);
- return 0;
- }
-
- pos += num;
-
- if (!_get_one_integrity_setting(cmd, settings, key, val))
- return_0;
- }
- }
-
- return 1;
-}
-
-int get_integrity_options(struct cmd_context *cmd, const char **arg, const char **meta_name,
- struct integrity_settings *set)
-{
- *arg = NULL;
- *meta_name = NULL;
- memset(set, 0, sizeof(struct integrity_settings));
-
- if (arg_int_value(cmd, integrity_ARG, 0))
- *arg = "y";
- else
- *arg = "n";
-
- /*
- * TODO: set *meta_name to some option value that controls the
- * location/placement/allocation of integrity metadata.
- * (It was previously a PV name to allocate from or an LV name
- * to use as the metadata LV.)
- */
-
- if (arg_is_set(cmd, integritysettings_ARG)) {
- if (!_get_integrity_settings(cmd, set))
- return_0;
- }
-
- return 1;
-}
-
/* FIXME move to lib */
static int _pv_change_tag(struct physical_volume *pv, const char *tag, int addtag)
{
diff --git a/tools/tools.h b/tools/tools.h
index 097017eff..7f2434d06 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -212,6 +212,8 @@ unsigned grouped_arg_is_set(const struct arg_values *av, int a);
const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def);
int32_t grouped_arg_int_value(const struct arg_values *av, int a, const int32_t def);
+int integrity_mode_set(const char *mode, struct integrity_settings *settings);
+
const char *command_name(struct cmd_context *cmd);
int pvmove_poll(struct cmd_context *cmd, const char *pv_name, const char *uuid,
@@ -235,9 +237,6 @@ struct lv_prop *get_lv_prop(int lvp_enum);
struct lv_type *get_lv_type(int lvt_enum);
struct command *get_command(int cmd_enum);
-int get_integrity_options(struct cmd_context *cmd, const char **arg, const char **meta_name,
- struct integrity_settings *set);
-
int lvchange_properties_cmd(struct cmd_context *cmd, int argc, char **argv);
int lvchange_activate_cmd(struct cmd_context *cmd, int argc, char **argv);
int lvchange_refresh_cmd(struct cmd_context *cmd, int argc, char **argv);