summaryrefslogtreecommitdiff
path: root/lib/raid/raid.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2019-11-20 16:07:27 -0600
committerDavid Teigland <teigland@redhat.com>2019-12-13 10:25:09 -0600
commit8ac1361dec159d5fc16e5128d4e80011ace56648 (patch)
treecfd072c0fbfbc103db8721457f826ea5a923d74c /lib/raid/raid.c
parent2173bdb82177fc687474b72561742955cb292522 (diff)
downloadlvm2-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.c36
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, &params))
return_0;