diff options
author | David Teigland <teigland@redhat.com> | 2019-11-20 16:07:27 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2019-12-13 10:25:09 -0600 |
commit | 8ac1361dec159d5fc16e5128d4e80011ace56648 (patch) | |
tree | cfd072c0fbfbc103db8721457f826ea5a923d74c /lib/raid/raid.c | |
parent | 2173bdb82177fc687474b72561742955cb292522 (diff) | |
download | lvm2-dev-dct-integrity15.tar.gz |
dm-integrity supportdev-dct-integrity15
dm-integrity stores checksums of the data written to an
LV, and returns an error if data read from the LV does
not match the previously saved checksum.
Create a linear LV with a dm-integrity layer above it:
lvcreate --type integrity --integrity String [options]
Create a raid1 LV with a dm-integrity layer over each
raid image:
lvcreate --type raid1 --integrity y [options]
Add a dm-integrity layer to an existing linear LV,
or to each image of an existing raid1 LV:
lvconvert --integrity y LV
Remove the dm-integrity layer from a linear LV, or
from the images of a raid1 LV:
lvconvert --integrity n LV
Integrity metadata:
The --integrity String specifies if the dm-integrity
metadata (checksums) should be interleaved with data
blocks, or written to a separate external LV.
--integrity external (default)
Use integrity with metadata on a separate LV.
Allows removing integrity from the LV later.
--integrity y
Same as integrity external.
--integrity n
Remove integrity (external metadata only.)
--integrity internal
Use integrity with metadata interleaved with
data on the same LV.
Only allowed with new linear LVs.
Internal integrity cannot be removed from an LV.
Around 1% of the LV size is used for integrity metadata.
Command variations:
lvcreate --type integrity -n Name -L Size VG
[Uses integrity external, the default.]
lvcreate --integrity y|external -n Name -L Size VG
[Uses type integrity, which is implied.]
lvcreate --integrity internal -n Name -L Size VG
[Uses type integrity, which is implied.]
lvcreate --type raid1 --integrity y -m Num -n Name -L Size VG
[Uses type integrity for each raid image.]
lvconvert --type integrity LV
[Converts linear LV to type integrity.]
lvconvert --integrity y|external LV
[Converts linear LV to type integrity, or each
image to type integrity in a raid1 LV.]
Options:
--integritymetadata LV
Use the specified LV for external metadata.
Allows specific device placement of metadata.
Without this option, the command creates a
hidden LV (with an _imeta suffix) to hold the
metadata. (Not usable with raid1+integrity.)
--integritysettings String
set dm-integrity parameters, e.g. to use a journal
instead of bitmap, --integritysettings "mode=J".
Example:
$ lvcreate --integrity external -n lvex -L1G vg
$ lvs -a vg
LV VG Attr LSize Origin
lvex vg gwi-a----- 1.00g [lvex_iorig]
[lvex_imeta] vg ewi-ao---- 12.00m
[lvex_iorig] vg -wi-ao---- 1.00g
$ lvcreate --integrity internal -n lvin -L1G vg
$ lvs -a vg
LV VG Attr LSize Origin
lvin vg gwi-a----- 1.00g [lvin_iorig]
[lvin_iorig] vg -wi-ao---- 1.00g
$ lvcreate --type raid1 --integrity y -m 1 -n lver -L1G vg
$ lvs -a vg
LV VG Attr LSize Origin
lver vg rwi-a-r--- 1.00g
[lver_rimage_0] vg gwi-aor--- 1.00g [lver_rimage_0_iorig]
[lver_rimage_0_imeta] vg ewi-ao---- 12.00m
[lver_rimage_0_iorig] vg -wi-ao---- 1.00g
[lver_rimage_1] vg gwi-aor--- 1.00g [lver_rimage_1_iorig]
[lver_rimage_1_imeta] vg ewi-ao---- 12.00m
[lver_rimage_1_iorig] vg -wi-ao---- 1.00g
[lver_rmeta_0] vg ewi-aor--- 4.00m
[lver_rmeta_1] vg ewi-aor--- 4.00m
Diffstat (limited to 'lib/raid/raid.c')
-rw-r--r-- | lib/raid/raid.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/raid/raid.c b/lib/raid/raid.c index e88a15408..48b63a31a 100644 --- a/lib/raid/raid.c +++ b/lib/raid/raid.c @@ -240,6 +240,26 @@ static int _raid_text_export(const struct lv_segment *seg, struct formatter *f) return _raid_text_export_raid(seg, f); } +static int _image_integrity_data_sectors(struct lv_segment *seg, uint64_t *data_sectors) +{ + struct logical_volume *lv_image; + struct lv_segment *seg_image; + int s; + + *data_sectors = 0; + + for (s = 0; s < seg->area_count; s++) { + lv_image = seg_lv(seg, s); + + if (lv_is_integrity(lv_image)) { + seg_image = first_seg(lv_image); + *data_sectors = seg_image->integrity_data_sectors; + return 1; + } + } + return 1; +} + static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), struct dm_pool *mem __attribute__((unused)), struct cmd_context *cmd __attribute__((unused)), @@ -256,6 +276,7 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), uint64_t writemostly[RAID_BITMAP_SIZE] = { 0 }; struct dm_tree_node_raid_params_v2 params = { 0 }; unsigned attrs; + uint64_t integrity_data_sectors = 0; if (seg_is_raid4(seg)) { if (!_raid_target_present(cmd, NULL, &attrs) || @@ -351,6 +372,21 @@ static int _raid_add_target_line(struct dev_manager *dm __attribute__((unused)), params.stripe_size = seg->stripe_size; params.flags = flags; + /* + * The len needs to be reduced only when the raid images are using + * integrity with internal metadata, which reduces the usable + * size of the image, and needs to be reflected in the dm table + * that's loaded. (internal metadata is not currently allowed + * with raid, so this is unused.) + */ + if (!_image_integrity_data_sectors(seg, &integrity_data_sectors)) + return_0; + if (integrity_data_sectors) { + log_debug("Reducing raid size from %llu to integrity_data_sectors %llu", + (unsigned long long)len, (unsigned long long)integrity_data_sectors); + len = integrity_data_sectors; + } + if (!dm_tree_node_add_raid_target_with_params_v2(node, len, ¶ms)) return_0; |