summaryrefslogtreecommitdiff
path: root/tools/lvcreate.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-03 15:44:11 -0600
commit39f781ca21fe1fac49705662c52ea20fdfbbc257 (patch)
tree114ddb4f2c17c3a4f0d90251df3950d745d30172 /tools/lvcreate.c
parentf88f7c0fdcdfbefa37df6adb36a637526bd7e93b (diff)
downloadlvm2-dev-dct-integrity5.tar.gz
Add dm-integrity supportdev-dct-integrity5
Create a linear LV with a dm-integrity layer added above it. The dm-integrity layer stores checksums of the data written to the LV, and returns an error if data read from the LV does not match the previously saved checksum. lvcreate --type integrity --integrity String [options] 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) Store integrity metadata on a separate LV. Allows removing integrity from the LV later. --integrity internal Store integrity metadata interleaved with data on the same LV. Around 1% of the LV size will be used for integrity metadata. --integrity y Enable default integrity settings (external). Command variations: lvcreate --type integrity -n Name -L Size VG [--integrity external is the default] lvcreate --integrity external -n Name -L Size VG [--integrity external implies --type integrity] lvcreate --integrity y -n Name -L Size VG [--integrity y uses default/external, and implies --type integrity] lvcreate --integrity internal -n Name -L Size VG [--integrity internal implies --type integrity] 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. --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 -wi-a----- 1.00g [lvex_iorig] [lvex_imeta] vg -wi-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 -wi-a----- 1.00g [lvin_iorig] [lvin_iorig] vg -wi-ao---- 1.00g Zeroing: After a new integrity LV is created, zeroes are written to the entire LV to initialize integrity metadata (checksums). Without this initialization, the LV will return read errors for any unwritten (and uninitialized) data. A large LV may take a long time to zero. The -Zn option can be used to disable the whole-LV zeroing, or the lvcreate command can be canceled while zeroing the new LV. In either case, the user may write to the entire LV to initialize the integrity metadata themselves. TODO: - add command to remove intregrity from an LV (only for external), i.e. lvconvert --integrity none LV - let integrity be used by raid images
Diffstat (limited to 'tools/lvcreate.c')
-rw-r--r--tools/lvcreate.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index ebe6c9f46..31110b2c3 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -785,6 +785,8 @@ 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;
@@ -1218,6 +1220,11 @@ static int _lvcreate_params(struct cmd_context *cmd,
}
}
+ if (seg_is_integrity(lp)) {
+ if (!get_integrity_options(cmd, &lp->integrity_arg, &lp->integrity_meta_name, &lp->integrity_settings))
+ return 0;
+ }
+
lcp->pv_count = argc;
lcp->pvs = argv;
@@ -1702,6 +1709,24 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name,
lp->pool_name ? : "with generated name", lp->vg_name, lp->segtype->name);
}
+ /*
+ * Create an LV to hold integrity metadata when:
+ *
+ * . The user wants external (not internal) metadata. External
+ * is indicated by: no option set (external is default), or
+ * --integrity y|external.
+ *
+ * . The user did not specify an existing metadata LV with
+ * --integritymetadata, saved as lp->integrity_meta_name.
+ */
+ if (seg_is_integrity(lp) && !lp->integrity_meta_name &&
+ (!lp->integrity_arg ||
+ !strcmp(lp->integrity_arg, "external") ||
+ !strcmp(lp->integrity_arg, "y"))) {
+ if (!lv_create_integrity_metadata(cmd, vg, lp))
+ goto_out;
+ }
+
if (vg->lock_type && !strcmp(vg->lock_type, "sanlock")) {
if (!handle_sanlock_lv(cmd, vg)) {
log_error("No space for sanlock lock, extend the internal lvmlock LV.");
@@ -1775,5 +1800,21 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
_destroy_lvcreate_params(&lp);
destroy_processing_handle(cmd, handle);
+
+ /*
+ * FIXME: make this interruptible. If the user cancels the zeroing,
+ * they can either use the LV without it being zeroed, or can finish
+ * zeroing it themselves, e.g. with dd.
+ *
+ * FIXME: if the user asked for the lv to be created in inactive
+ * (-an) then deactivate the LV after zeroing.
+ */
+ if (lp.post_zero_bytes) {
+ if (!lp.zero)
+ log_warn("WARNING: not zeroing LV, integrity read errors may occur.");
+ else
+ zero_lv_name(cmd, lp.vg_name, lp.lv_name, lp.post_zero_bytes);
+ }
+
return ret;
}