mirror of
git://sourceware.org/git/lvm2.git
synced 2026-01-25 00:32:58 +03:00
Compare commits
1 Commits
dev-dct-in
...
dev-dct-in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0bbc94900 |
@@ -105,7 +105,6 @@ static const struct flag _lv_flags[] = {
|
||||
{LV_VDO_POOL_DATA, NULL, 0},
|
||||
{WRITECACHE, NULL, 0},
|
||||
{INTEGRITY, NULL, 0},
|
||||
{INTEGRITY_METADATA, NULL, 0},
|
||||
{LV_PENDING_DELETE, NULL, 0}, /* FIXME Display like COMPATIBLE_FLAG */
|
||||
{LV_REMOVED, NULL, 0},
|
||||
{LV_UNCOMMITTED, NULL, 0},
|
||||
|
||||
@@ -156,9 +156,6 @@ static int _integrity_text_import(struct lv_segment *seg,
|
||||
seg->integrity_meta_dev = meta_lv;
|
||||
seg->lv->status |= INTEGRITY;
|
||||
|
||||
if (meta_lv)
|
||||
meta_lv->status |= INTEGRITY_METADATA;
|
||||
|
||||
if (meta_lv && !add_seg_to_segs_using_this_lv(meta_lv, seg))
|
||||
return_0;
|
||||
|
||||
|
||||
@@ -252,6 +252,8 @@ struct label *label_create(struct labeller *labeller)
|
||||
/* global variable for accessing the bcache populated by label scan */
|
||||
struct bcache *scan_bcache;
|
||||
|
||||
#define BCACHE_BLOCK_SIZE_IN_SECTORS 256 /* 256*512 = 128K */
|
||||
|
||||
static bool _in_bcache(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
|
||||
@@ -118,14 +118,6 @@ int label_scan_open(struct device *dev);
|
||||
int label_scan_open_excl(struct device *dev);
|
||||
int label_scan_open_rw(struct device *dev);
|
||||
|
||||
/*
|
||||
* These are the sizes the label.c uses to set up
|
||||
* and use bcache (they are not bcache restrictions
|
||||
* or defs.)
|
||||
*/
|
||||
#define BCACHE_BLOCK_SIZE_IN_SECTORS 256 /* 256*512 = 128K */
|
||||
#define BCACHE_BLOCK_SIZE_IN_BYTES 131072
|
||||
|
||||
/*
|
||||
* Wrappers around bcache equivalents.
|
||||
* (these make it easier to disable bcache and revert to direct rw if needed)
|
||||
|
||||
@@ -29,28 +29,6 @@
|
||||
|
||||
#define ONE_MB_IN_BYTES 1048576
|
||||
|
||||
int lv_is_integrity_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 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Every 500M of data needs 4M of metadata.
|
||||
* (From trial and error testing.)
|
||||
*/
|
||||
static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
|
||||
{
|
||||
return ((lv_size_bytes / (500 * ONE_MB_IN_BYTES)) + 1) * (4 * ONE_MB_IN_BYTES);
|
||||
}
|
||||
|
||||
/*
|
||||
* The user wants external metadata, but did not specify an existing
|
||||
* LV to hold metadata, so create an LV for metadata. Save it in
|
||||
@@ -61,7 +39,7 @@ int lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
struct lvcreate_params *lp)
|
||||
{
|
||||
char metaname[NAME_LEN];
|
||||
uint64_t lv_size_bytes, meta_bytes, meta_sectors;
|
||||
uint32_t extent_bytes;
|
||||
struct logical_volume *lv;
|
||||
struct lvcreate_params lp_meta = {
|
||||
.activate = CHANGE_AN,
|
||||
@@ -75,7 +53,6 @@ int lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
.vg_name = vg->name,
|
||||
.zero = 0,
|
||||
.wipe_signatures = 0,
|
||||
.suppress_zero_warn = 1,
|
||||
};
|
||||
|
||||
if (dm_snprintf(metaname, NAME_LEN, "%s_imeta", lp->lv_name) < 0) {
|
||||
@@ -86,15 +63,12 @@ int lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
if (!(lp_meta.lv_name = strdup(metaname)))
|
||||
return_0;
|
||||
|
||||
lp_meta.pvh = lp->pvh;
|
||||
/* TODO: set pvh per command line */
|
||||
/* TODO: scale size according to LV size. */
|
||||
extent_bytes = vg->extent_size * SECTOR_SIZE;
|
||||
lp_meta.extents = (4 * ONE_MB_IN_BYTES) / extent_bytes;
|
||||
|
||||
lv_size_bytes = lp->extents * vg->extent_size * 512;
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes);
|
||||
meta_sectors = meta_bytes / 512;
|
||||
lp_meta.extents = meta_sectors / vg->extent_size;
|
||||
|
||||
log_print("Creating integrity metadata LV %s with size %s.",
|
||||
metaname, display_size(cmd, meta_sectors));
|
||||
log_debug("Creating integrity metadata LV with %u extents", lp_meta.extents);
|
||||
|
||||
dm_list_init(&lp_meta.tags);
|
||||
|
||||
@@ -113,7 +87,6 @@ int lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
static int _get_provided_data_sectors(struct logical_volume *lv, uint64_t *provided_data_sectors)
|
||||
{
|
||||
struct lv_with_info_and_seg_status status;
|
||||
uint64_t data_sectors, extra_sectors;
|
||||
|
||||
memset(&status, 0, sizeof(status));
|
||||
status.seg_status.type = SEG_STATUS_NONE;
|
||||
@@ -142,15 +115,7 @@ static int _get_provided_data_sectors(struct logical_volume *lv, uint64_t *provi
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data_sectors = status.seg_status.integrity->provided_data_sectors;
|
||||
|
||||
if ((extra_sectors = (data_sectors % lv->vg->extent_size))) {
|
||||
data_sectors -= extra_sectors;
|
||||
log_debug("Reduce provided_data_sectors by %llu to %llu for extent alignment",
|
||||
(unsigned long long)extra_sectors, (unsigned long long)data_sectors);
|
||||
}
|
||||
|
||||
*provided_data_sectors = data_sectors;
|
||||
*provided_data_sectors = status.seg_status.integrity->provided_data_sectors;
|
||||
|
||||
dm_pool_destroy(status.seg_status.mem);
|
||||
return 1;
|
||||
@@ -160,243 +125,18 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lv_remove_integrity(struct logical_volume *lv)
|
||||
{
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct logical_volume *origin;
|
||||
struct logical_volume *meta_lv;
|
||||
|
||||
if (!seg_is_integrity(seg)) {
|
||||
log_error("LV %s segment is not integrity.", display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(meta_lv = seg->integrity_meta_dev)) {
|
||||
log_error("LV %s segment has no integrity metadata device.", display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(origin = 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_set_visible(seg->integrity_meta_dev);
|
||||
|
||||
lv->status &= ~INTEGRITY;
|
||||
meta_lv->status &= ~INTEGRITY_METADATA;
|
||||
|
||||
seg->integrity_meta_dev = NULL;
|
||||
|
||||
if (!remove_layer_from_lv(lv, origin))
|
||||
return_0;
|
||||
|
||||
if (!lv_remove(origin))
|
||||
return_0;
|
||||
|
||||
if (!lv_remove(meta_lv))
|
||||
log_warn("WARNING: failed to remove integrity metadata LV.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add integrity to each raid image.
|
||||
*
|
||||
* for each rimage_N:
|
||||
* . create and allocate a new linear LV rimage_N_imeta
|
||||
* . create a new empty linear LV rimage_N_iorig
|
||||
* . move the segments from rimage_N to rimage_N_iorig
|
||||
* . add an integrity segment to rimage_N with
|
||||
* origin=rimage_N_iorig, meta_dev=rimage_N_imeta
|
||||
*
|
||||
* Before:
|
||||
* rimage_0
|
||||
* segment1: striped: pv0:A
|
||||
* rimage_1
|
||||
* segment1: striped: pv1:B
|
||||
*
|
||||
* After:
|
||||
* rimage_0
|
||||
* segment1: integrity: rimage_0_iorig, rimage_0_imeta
|
||||
* rimage_1
|
||||
* segment1: integrity: rimage_1_iorig, rimage_1_imeta
|
||||
* rimage_0_iorig
|
||||
* segment1: striped: pv0:A
|
||||
* rimage_1_iorig
|
||||
* segment1: striped: pv1:B
|
||||
* rimage_0_imeta
|
||||
* segment1: striped: pv2:A
|
||||
* rimage_1_imeta
|
||||
* segment1: striped: pv2:B
|
||||
*
|
||||
*/
|
||||
|
||||
static int _lv_add_integrity_to_raid(struct logical_volume *lv, const char *arg,
|
||||
struct integrity_settings *settings,
|
||||
struct dm_list *pvh)
|
||||
{
|
||||
struct lvcreate_params lp;
|
||||
struct logical_volume *imeta_lvs[DEFAULT_RAID_MAX_IMAGES];
|
||||
struct cmd_context *cmd = lv->vg->cmd;
|
||||
struct volume_group *vg = lv->vg;
|
||||
struct logical_volume *lv_image, *lv_imeta, *lv_iorig;
|
||||
struct lv_segment *seg_top, *seg_image;
|
||||
const struct segment_type *segtype;
|
||||
struct integrity_settings *set;
|
||||
uint64_t lv_size_sectors;
|
||||
uint32_t area_count, s;
|
||||
int ret = 1;
|
||||
|
||||
memset(imeta_lvs, 0, sizeof(imeta_lvs));
|
||||
|
||||
if (dm_list_size(&lv->segments) != 1)
|
||||
return_0;
|
||||
|
||||
seg_top = first_seg(lv);
|
||||
area_count = seg_top->area_count;
|
||||
|
||||
/*
|
||||
* For each rimage, create an _imeta LV for integrity metadata.
|
||||
* Each needs to be zeroed.
|
||||
*/
|
||||
for (s = 0; s < area_count; s++) {
|
||||
struct logical_volume *meta_lv;
|
||||
struct wipe_params wipe;
|
||||
|
||||
if (s >= DEFAULT_RAID_MAX_IMAGES)
|
||||
return_0;
|
||||
|
||||
lv_image = seg_lv(seg_top, s);
|
||||
|
||||
if (!seg_is_striped(first_seg(lv_image))) {
|
||||
log_error("raid1 image must be linear to add integrity");
|
||||
return_0;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate a new linear LV NAME_rimage_N_imeta
|
||||
* lv_create_integrity_metadata() returns its result in lp
|
||||
*/
|
||||
memset(&lp, 0, sizeof(lp));
|
||||
lp.lv_name = lv_image->name;
|
||||
lp.pvh = pvh;
|
||||
lp.extents = lv_image->size / vg->extent_size;
|
||||
|
||||
if (!lv_create_integrity_metadata(cmd, vg, &lp)) {
|
||||
return_0;
|
||||
}
|
||||
meta_lv = lp.integrity_meta_lv;
|
||||
|
||||
/*
|
||||
* dm-integrity requires the metadata LV header to be zeroed.
|
||||
*/
|
||||
|
||||
if (!activate_lv(cmd, meta_lv)) {
|
||||
log_error("Failed to activate LV %s to zero", display_lvname(meta_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&wipe, 0, sizeof(wipe));
|
||||
wipe.do_zero = 1;
|
||||
wipe.zero_sectors = 8;
|
||||
|
||||
if (!wipe_lv(meta_lv, wipe)) {
|
||||
log_error("Failed to zero LV for integrity metadata %s", display_lvname(meta_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(cmd, meta_lv)) {
|
||||
log_error("Failed to deactivate LV %s after zero", display_lvname(meta_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used below to set up the new integrity segment. */
|
||||
imeta_lvs[s] = meta_lv;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each rimage, move its segments to a new rimage_iorig and give
|
||||
* the rimage a new integrity segment.
|
||||
*/
|
||||
for (s = 0; s < area_count; s++) {
|
||||
lv_image = seg_lv(seg_top, s);
|
||||
|
||||
lv_size_sectors = lv_image->size;
|
||||
|
||||
lv_imeta = imeta_lvs[s]; /* integrity metadata lv created above */
|
||||
|
||||
if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_INTEGRITY)))
|
||||
return_0;
|
||||
|
||||
log_print("Adding integrity to raid image %s", lv_image->name);
|
||||
|
||||
/*
|
||||
* "lv_iorig" is a new LV with new id, but with the segments
|
||||
* from "lv_image". "lv_image" keeps the existing name and id,
|
||||
* but gets a new integrity segment, in place of the segments
|
||||
* that were moved to lv_iorig.
|
||||
*/
|
||||
if (!(lv_iorig = insert_layer_for_lv(cmd, lv_image, INTEGRITY, "_iorig")))
|
||||
return_0;
|
||||
|
||||
lv_image->status |= INTEGRITY;
|
||||
lv_imeta->status |= INTEGRITY_METADATA;
|
||||
lv_set_hidden(lv_imeta);
|
||||
|
||||
/*
|
||||
* Set up the new first segment of lv_image as integrity.
|
||||
*/
|
||||
seg_image = first_seg(lv_image);
|
||||
seg_image->segtype = segtype;
|
||||
seg_image->integrity_data_sectors = lv_size_sectors;
|
||||
seg_image->integrity_meta_dev = lv_imeta;
|
||||
|
||||
memcpy(&seg_image->integrity_settings, settings, sizeof(struct integrity_settings));
|
||||
set = &seg_image->integrity_settings;
|
||||
|
||||
if (!set->mode[0])
|
||||
set->mode[0] = DEFAULT_MODE;
|
||||
|
||||
if (!set->tag_size)
|
||||
set->tag_size = DEFAULT_TAG_SIZE;
|
||||
|
||||
if (!set->internal_hash)
|
||||
set->internal_hash = DEFAULT_INTERNAL_HASH;
|
||||
}
|
||||
|
||||
log_debug("Write VG with integrity added to LV");
|
||||
|
||||
if (!vg_write(vg) || !vg_commit(vg))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
struct logical_volume *meta_lv_created,
|
||||
const char *meta_name,
|
||||
struct integrity_settings *settings,
|
||||
struct dm_list *pvh)
|
||||
struct integrity_settings *settings)
|
||||
{
|
||||
struct cmd_context *cmd = lv->vg->cmd;
|
||||
struct volume_group *vg = lv->vg;
|
||||
struct integrity_settings *set;
|
||||
struct logical_volume *lv_orig;
|
||||
struct logical_volume *meta_lv = NULL;
|
||||
const struct segment_type *segtype;
|
||||
struct lv_segment *seg;
|
||||
uint64_t meta_bytes, meta_sectors;
|
||||
uint64_t lv_size_sectors;
|
||||
int ret = 1;
|
||||
|
||||
if (lv_is_raid(lv))
|
||||
return _lv_add_integrity_to_raid(lv, arg, settings, pvh);
|
||||
|
||||
lv_size_sectors = lv->size;
|
||||
int ret;
|
||||
|
||||
if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_INTEGRITY)))
|
||||
return_0;
|
||||
@@ -447,19 +187,10 @@ int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
if (meta_lv_created)
|
||||
meta_lv = meta_lv_created;
|
||||
else if (meta_name) {
|
||||
if (!(meta_lv = find_lv(vg, meta_name))) {
|
||||
if (!(meta_lv = find_lv(lv->vg, meta_name))) {
|
||||
log_error("LV %s not found.", meta_name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv->size * 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));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -477,41 +208,20 @@ int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
*/
|
||||
|
||||
if (meta_lv) {
|
||||
struct wipe_params wipe;
|
||||
|
||||
if (!sync_local_dev_names(cmd)) {
|
||||
log_error("Failed to sync local devices.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&wipe, 0, sizeof(wipe));
|
||||
wipe.do_zero = 1;
|
||||
wipe.zero_sectors = 8;
|
||||
|
||||
if (!wipe_lv(meta_lv, wipe)) {
|
||||
log_error("Failed to zero LV for integrity metadata %s", display_lvname(meta_lv));
|
||||
if (!activate_and_wipe_lv(meta_lv, 0)) {
|
||||
log_error("LV %s could not be zeroed.", display_lvname(meta_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(cmd, meta_lv)) {
|
||||
log_error("Failed to deactivate LV %s after zero", display_lvname(meta_lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
meta_lv->status |= INTEGRITY_METADATA;
|
||||
seg->integrity_data_sectors = lv_size_sectors;
|
||||
seg->integrity_data_sectors = seg->len;
|
||||
seg->integrity_meta_dev = meta_lv;
|
||||
lv_set_hidden(meta_lv);
|
||||
/* TODO: give meta_lv a suffix? e.g. _imeta */
|
||||
ret = 1;
|
||||
} else {
|
||||
/* dm-integrity wants temp/fake size of 1 to report usable size */
|
||||
seg->integrity_data_sectors = 1;
|
||||
@@ -536,11 +246,6 @@ int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (!seg->integrity_data_sectors) {
|
||||
log_error("LV size too small to include metadata.");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
lv->status |= LV_UNCOMMITTED;
|
||||
|
||||
if (!deactivate_lv(cmd, lv)) {
|
||||
@@ -552,11 +257,6 @@ int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
lv->status &= ~LV_NOSCAN;
|
||||
lv->status &= ~LV_TEMPORARY;
|
||||
}
|
||||
|
||||
log_debug("Write VG with integrity added to LV");
|
||||
|
||||
if (!vg_write(vg) || !vg_commit(vg))
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1202,13 +1202,10 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
|
||||
repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
|
||||
else if (lv_is_pool_metadata(lv) ||
|
||||
lv_is_pool_metadata_spare(lv) ||
|
||||
lv_is_raid_metadata(lv) ||
|
||||
lv_is_integrity_metadata(lv))
|
||||
lv_is_raid_metadata(lv))
|
||||
repstr[0] = 'e';
|
||||
else if (lv_is_cache_type(lv) || lv_is_writecache(lv))
|
||||
repstr[0] = 'C';
|
||||
else if (lv_is_integrity(lv))
|
||||
repstr[0] = 'g';
|
||||
else if (lv_is_raid(lv))
|
||||
repstr[0] = (lv_is_not_synced(lv)) ? 'R' : 'r';
|
||||
else if (lv_is_mirror(lv))
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "lib/datastruct/str_list.h"
|
||||
#include "lib/config/defaults.h"
|
||||
#include "lib/misc/lvm-exec.h"
|
||||
#include "lib/misc/lvm-signal.h"
|
||||
#include "lib/mm/memlock.h"
|
||||
#include "lib/locking/lvmlockd.h"
|
||||
#include "lib/label/label.h"
|
||||
@@ -56,8 +55,6 @@ typedef enum {
|
||||
#define A_POSITIONAL_FILL 0x40 /* Slots are positional and filled using PREFERRED */
|
||||
#define A_PARTITION_BY_TAGS 0x80 /* No allocated area may share any tag with any other */
|
||||
|
||||
#define ONE_MB_IN_BYTES 1048576
|
||||
|
||||
/*
|
||||
* Constant parameters during a single allocation attempt.
|
||||
*/
|
||||
@@ -137,9 +134,7 @@ enum {
|
||||
LV_TYPE_SANLOCK,
|
||||
LV_TYPE_CACHEVOL,
|
||||
LV_TYPE_WRITECACHE,
|
||||
LV_TYPE_WRITECACHEORIGIN,
|
||||
LV_TYPE_INTEGRITY,
|
||||
LV_TYPE_INTEGRITYORIGIN
|
||||
LV_TYPE_WRITECACHEORIGIN
|
||||
};
|
||||
|
||||
static const char *_lv_type_names[] = {
|
||||
@@ -195,8 +190,6 @@ static const char *_lv_type_names[] = {
|
||||
[LV_TYPE_CACHEVOL] = "cachevol",
|
||||
[LV_TYPE_WRITECACHE] = "writecache",
|
||||
[LV_TYPE_WRITECACHEORIGIN] = "writecacheorigin",
|
||||
[LV_TYPE_INTEGRITY] = "integrity",
|
||||
[LV_TYPE_INTEGRITYORIGIN] = "integrityorigin",
|
||||
};
|
||||
|
||||
static int _lv_layout_and_role_mirror(struct dm_pool *mem,
|
||||
@@ -468,43 +461,6 @@ bad:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _lv_layout_and_role_integrity(struct dm_pool *mem,
|
||||
const struct logical_volume *lv,
|
||||
struct dm_list *layout,
|
||||
struct dm_list *role,
|
||||
int *public_lv)
|
||||
{
|
||||
int top_level = 0;
|
||||
|
||||
/* non-top-level LVs */
|
||||
if (lv_is_integrity_metadata(lv)) {
|
||||
if (!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_INTEGRITY]) ||
|
||||
!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_METADATA]))
|
||||
goto_bad;
|
||||
} else if (lv_is_integrity_origin(lv)) {
|
||||
if (!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_INTEGRITY]) ||
|
||||
!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_ORIGIN]) ||
|
||||
!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_INTEGRITYORIGIN]))
|
||||
goto_bad;
|
||||
} else
|
||||
top_level = 1;
|
||||
|
||||
if (!top_level) {
|
||||
*public_lv = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* top-level LVs */
|
||||
if (lv_is_integrity(lv)) {
|
||||
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_INTEGRITY]))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
return 1;
|
||||
bad:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _lv_layout_and_role_thick_origin_snapshot(struct dm_pool *mem,
|
||||
const struct logical_volume *lv,
|
||||
struct dm_list *layout,
|
||||
@@ -621,11 +577,6 @@ int lv_layout_and_role(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
!_lv_layout_and_role_cache(mem, lv, *layout, *role, &public_lv))
|
||||
goto_bad;
|
||||
|
||||
/* Integrity related */
|
||||
if ((lv_is_integrity(lv) || lv_is_integrity_origin(lv) || lv_is_integrity_metadata(lv)) &&
|
||||
!_lv_layout_and_role_integrity(mem, lv, *layout, *role, &public_lv))
|
||||
goto_bad;
|
||||
|
||||
/* VDO and related */
|
||||
if (lv_is_vdo_type(lv) &&
|
||||
!_lv_layout_and_role_vdo(mem, lv, *layout, *role, &public_lv))
|
||||
@@ -7473,88 +7424,11 @@ int insert_layer_for_segments_on_pv(struct cmd_context *cmd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int zero_lv_name(struct cmd_context *cmd, const char *vg_name, const char *lv_name, uint64_t lv_size_bytes)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
struct device *dev;
|
||||
uint64_t off = 0, i = 0, j = 0;
|
||||
uint64_t zero_bytes;
|
||||
uint32_t extra_bytes;
|
||||
|
||||
if (dm_snprintf(name, sizeof(name), "%s%s/%s", cmd->dev_dir, vg_name, lv_name) < 0) {
|
||||
log_error("Device path name too long, device not zeroed (%s).", lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dev = dev_cache_get(cmd, name, NULL))) {
|
||||
log_error("Failed to find device %s: device not zeroed.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!label_scan_open_rw(dev)) {
|
||||
log_error("Failed to open %s: device not zeroed.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
zero_bytes = lv_size_bytes;
|
||||
|
||||
log_print("Zeroing %s %s... (cancel command to zero manually)",
|
||||
name, display_size(cmd, zero_bytes/512));
|
||||
|
||||
if ((extra_bytes = (zero_bytes % ONE_MB_IN_BYTES)))
|
||||
zero_bytes -= extra_bytes;
|
||||
|
||||
/*
|
||||
* Write 1MiB at a time to avoid going over bcache size.
|
||||
* Then write 128KiB (bcache block sizes) at a time to
|
||||
* cover remaining dev size.
|
||||
*/
|
||||
|
||||
sigint_allow();
|
||||
|
||||
for (i = 0; i < (zero_bytes / ONE_MB_IN_BYTES); i++) {
|
||||
off = i * ONE_MB_IN_BYTES;
|
||||
if (!dev_write_zeros(dev, off, (size_t)ONE_MB_IN_BYTES))
|
||||
log_error("Failed to zero LV at offset %llu.", (unsigned long long)off);
|
||||
|
||||
if (off && !(off % (1024 * ONE_MB_IN_BYTES)))
|
||||
log_print("Zeroed %s...", display_size(cmd, off/512));
|
||||
|
||||
if (sigint_caught()) {
|
||||
log_print("Zeroing canceled.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (extra_bytes) {
|
||||
log_debug("Zeroing final %u bytes at %llu.", extra_bytes, (unsigned long long)off);
|
||||
|
||||
for (j = 0; j < (extra_bytes / BCACHE_BLOCK_SIZE_IN_BYTES); j++) {
|
||||
off = i * ONE_MB_IN_BYTES + j * BCACHE_BLOCK_SIZE_IN_BYTES;
|
||||
if (!dev_write_zeros(dev, off, (size_t)BCACHE_BLOCK_SIZE_IN_BYTES))
|
||||
log_error("Failed to zero LV at offset %llu.", (unsigned long long)off);
|
||||
|
||||
if (sigint_caught()) {
|
||||
log_print("Zeroing canceled.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: bcache can't write partial blocks yet.
|
||||
* This shouldn't actually happen given current
|
||||
* usage where LV size is a multiple of extents.
|
||||
*/
|
||||
if ((extra_bytes = lv_size_bytes - (i * ONE_MB_IN_BYTES + j * BCACHE_BLOCK_SIZE_IN_BYTES)))
|
||||
log_warn("WARNING: last %llu bytes not zeroed.", (unsigned long long)extra_bytes);
|
||||
|
||||
out:
|
||||
sigint_restore();
|
||||
label_scan_invalidate(dev);
|
||||
return 1;
|
||||
}
|
||||
/* FIXME: copied from label.c */
|
||||
#define BCACHE_BLOCK_SIZE_IN_SECTORS 256 /* 256*512 = 128K */
|
||||
#define BCACHE_BLOCK_SIZE_IN_BYTES 131072
|
||||
#define ONE_MB_IN_BYTES 1048576
|
||||
#define ONE_MB_IN_SECTORS 2048 /* 2048 * 512 = 1048576 */
|
||||
|
||||
/*
|
||||
* Initialize the LV with 'value'.
|
||||
@@ -7614,7 +7488,44 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
|
||||
stack;
|
||||
}
|
||||
|
||||
if (wp.do_zero) {
|
||||
if (wp.do_zero && !wp.zero_value && (wp.zero_sectors >= ONE_MB_IN_SECTORS)) {
|
||||
uint64_t off = 0, i = 0, j = 0;
|
||||
uint64_t zero_bytes;
|
||||
uint32_t extra_bytes;
|
||||
|
||||
zero_bytes = wp.zero_sectors * 512;
|
||||
|
||||
if ((extra_bytes = (zero_bytes % ONE_MB_IN_BYTES)))
|
||||
zero_bytes -= extra_bytes;
|
||||
|
||||
log_print("Zeroing %llu MiB...", (unsigned long long)(zero_bytes / ONE_MB_IN_BYTES));
|
||||
|
||||
/*
|
||||
* Write 1MiB at a time to avoid going over bcache size.
|
||||
* Then write 128KiB at a time to cover remaining dev size.
|
||||
*/
|
||||
|
||||
for (i = 0; i < (zero_bytes / ONE_MB_IN_BYTES); i++) {
|
||||
off = i * ONE_MB_IN_BYTES;
|
||||
if (!dev_write_zeros(dev, off, (size_t)ONE_MB_IN_BYTES))
|
||||
log_error("Failed to zero LV at offset %llu.", (unsigned long long)off);
|
||||
}
|
||||
|
||||
if (extra_bytes) {
|
||||
log_warn("Zeroing %u bytes at %llu...", extra_bytes, (unsigned long long)off);
|
||||
|
||||
for (j = 0; j < (extra_bytes / BCACHE_BLOCK_SIZE_IN_BYTES); j++) {
|
||||
off = i * ONE_MB_IN_BYTES + j * BCACHE_BLOCK_SIZE_IN_BYTES;
|
||||
if (!dev_write_zeros(dev, off, (size_t)BCACHE_BLOCK_SIZE_IN_BYTES))
|
||||
log_error("Failed to zero LV at offset %llu.", (unsigned long long)off);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: bcache can't write partial block yet */
|
||||
if ((extra_bytes = (wp.zero_sectors * 512) - (i * ONE_MB_IN_BYTES + j * BCACHE_BLOCK_SIZE_IN_BYTES)))
|
||||
log_warn("WARNING: last %llu bytes not zeroed.", (unsigned long long)extra_bytes);
|
||||
|
||||
} else if (wp.do_zero) {
|
||||
zero_sectors = wp.zero_sectors ? : UINT64_C(4096) >> SECTOR_SHIFT;
|
||||
|
||||
if (zero_sectors > lv->size)
|
||||
@@ -7825,14 +7736,10 @@ static int _should_wipe_lv(struct lvcreate_params *lp,
|
||||
first_seg(first_seg(lv)->pool_lv)->zero_new_blocks))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* dm-integrity requires the first sector (integrity superblock) to be
|
||||
* zero when creating a new integrity device.
|
||||
* TODO: print a warning or error if the user specifically
|
||||
* asks for no wiping or zeroing?
|
||||
*/
|
||||
if (seg_is_integrity(lp) || (seg_is_raid1(lp) && lp->integrity_arg))
|
||||
return 1;
|
||||
if (seg_is_integrity(lp) && (!lp->zero || !(lv->status & LVM_WRITE))) {
|
||||
log_warn("WARNING: --zero not enabled, integrity will not be initialized and may cause read errors.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cannot zero read-only volume */
|
||||
if ((lv->status & LVM_WRITE) &&
|
||||
@@ -8091,6 +7998,13 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
return_0;
|
||||
|
||||
} else if (seg_is_integrity(lp)) {
|
||||
/*
|
||||
* TODO: if using internal metadata, estimate the amount of metadata
|
||||
* that will be needed, and add this to the amount of PV space being
|
||||
* allocated so that the usable LV size is what the user requested.
|
||||
* Or, just request an extra extent_size bytes, then round the
|
||||
* provided_data_sectors down to be an extent_size multiple.
|
||||
*/
|
||||
if (!(create_segtype = get_segtype_from_string(vg->cmd, SEG_TYPE_NAME_STRIPED)))
|
||||
return_0;
|
||||
|
||||
@@ -8318,6 +8232,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
}
|
||||
}
|
||||
|
||||
if (seg_is_integrity(lp)) {
|
||||
if (!lv_add_integrity(lv, lp->integrity_arg, lp->integrity_meta_lv,
|
||||
lp->integrity_meta_name, &lp->integrity_settings))
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
lv_set_activation_skip(lv, lp->activation_skip & ACTIVATION_SKIP_SET,
|
||||
lp->activation_skip & ACTIVATION_SKIP_SET_ENABLED);
|
||||
/*
|
||||
@@ -8437,25 +8357,27 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
goto revert_new_lv;
|
||||
}
|
||||
lv->status &= ~LV_TEMPORARY;
|
||||
|
||||
} else if (seg_is_integrity(lp) || (seg_is_raid1(lp) && lp->integrity_arg)) {
|
||||
/*
|
||||
* Activate the new origin LV so it can be zeroed/wiped
|
||||
* below before adding integrity.
|
||||
*/
|
||||
lv->status |= LV_TEMPORARY;
|
||||
if (!activate_lv(cmd, lv)) {
|
||||
log_error("Failed to activate new LV for wiping.");
|
||||
goto revert_new_lv;
|
||||
}
|
||||
lv->status &= ~LV_TEMPORARY;
|
||||
|
||||
} else if (!lv_active_change(cmd, lv, lp->activate)) {
|
||||
log_error("Failed to activate new LV %s.", display_lvname(lv));
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
|
||||
if (_should_wipe_lv(lp, lv, !lp->suppress_zero_warn)) {
|
||||
if (seg_is_integrity(lp)) {
|
||||
struct wipe_params wipe;
|
||||
|
||||
memset(&wipe, 0, sizeof(wipe));
|
||||
wipe.do_zero = 1;
|
||||
wipe.zero_sectors = first_seg(lv)->integrity_data_sectors;
|
||||
|
||||
if (!_should_wipe_lv(lp, lv, 1))
|
||||
goto_out;
|
||||
|
||||
if (!wipe_lv(lv, wipe))
|
||||
log_error("Failed to zero LV.");
|
||||
|
||||
goto out;
|
||||
|
||||
} else if (_should_wipe_lv(lp, lv, !lp->suppress_zero_warn)) {
|
||||
if (!wipe_lv(lv, (struct wipe_params)
|
||||
{
|
||||
.do_zero = lp->zero,
|
||||
@@ -8469,53 +8391,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
}
|
||||
}
|
||||
|
||||
if (seg_is_integrity(lp) || (seg_is_raid1(lp) && lp->integrity_arg)) {
|
||||
log_verbose("Adding integrity to new LV");
|
||||
|
||||
/* Origin is active from zeroing, deactivate to add integrity. */
|
||||
|
||||
if (!deactivate_lv(cmd, lv)) {
|
||||
log_error("Failed to deactivate LV to add integrity");
|
||||
goto revert_new_lv;
|
||||
}
|
||||
|
||||
if (!lv_add_integrity(lv, lp->integrity_arg, lp->integrity_meta_lv,
|
||||
lp->integrity_meta_name, &lp->integrity_settings, lp->pvh))
|
||||
goto revert_new_lv;
|
||||
|
||||
backup(vg);
|
||||
|
||||
/*
|
||||
* The standard option combination should be -Zy -ay, in which
|
||||
* case we activate here, and zero at the end of the command.
|
||||
* The invalid combination -Zy -an has been prevented earlier.
|
||||
* The combination -Zn -an involves no zeroing or activation.
|
||||
* For combination -Zn -ay we activate here.
|
||||
*/
|
||||
if (lp->zero) {
|
||||
/* Activate for zeroing at the end of lvcreate. */
|
||||
if (!activate_lv(cmd, lv)) {
|
||||
log_error("Failed to activate LV %s.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
} else if (!lp->zero && is_change_activating(lp->activate)) {
|
||||
if (!activate_lv(cmd, lv)) {
|
||||
log_error("Failed to activate LV %s.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The entire LV is zeroed, which can take a long time,
|
||||
* so defer this to the end of the command when no locks
|
||||
* are held, and the command can be canceled without
|
||||
* problems (if the user doesn't want to wait, or wants
|
||||
* to do the zeroing themselves.)
|
||||
*/
|
||||
lp->integrity_bytes_to_zero = first_seg(lv)->integrity_data_sectors * 512;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (seg_is_vdo_pool(lp)) {
|
||||
if (!convert_vdo_pool_lv(lv, &lp->vdo_params, &lp->virtual_extents)) {
|
||||
stack;
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
|
||||
//#define POSTORDER_FLAG UINT64_C(0x0000000002000000) /* Not real flags, reserved for
|
||||
//#define POSTORDER_OPEN_FLAG UINT64_C(0x0000000004000000) temporary use inside vg_read_internal. */
|
||||
#define INTEGRITY_METADATA UINT64_C(0x0000000004000000) /* LV - Internal use only */
|
||||
#define LV_UNCOMMITTED UINT64_C(0x0000000002000000)
|
||||
#define VIRTUAL_ORIGIN UINT64_C(0x0000000008000000) /* LV - internal use only */
|
||||
|
||||
@@ -264,8 +263,7 @@
|
||||
#define lv_is_pool_metadata_spare(lv) (((lv)->status & POOL_METADATA_SPARE) ? 1 : 0)
|
||||
#define lv_is_lockd_sanlock_lv(lv) (((lv)->status & LOCKD_SANLOCK_LV) ? 1 : 0)
|
||||
#define lv_is_writecache(lv) (((lv)->status & WRITECACHE) ? 1 : 0)
|
||||
#define lv_is_integrity(lv) (((lv)->status & INTEGRITY) ? 1 : 0)
|
||||
#define lv_is_integrity_metadata(lv) (((lv)->status & INTEGRITY_METADATA) ? 1 : 0)
|
||||
#define lv_is_integrity(lv) (((lv)->status & INTEGRITY) ? 1 : 0)
|
||||
|
||||
#define lv_is_vdo(lv) (((lv)->status & LV_VDO) ? 1 : 0)
|
||||
#define lv_is_vdo_pool(lv) (((lv)->status & LV_VDO_POOL) ? 1 : 0)
|
||||
@@ -277,11 +275,9 @@
|
||||
/* Recognize component LV (matching lib/misc/lvm-string.c _lvname_has_reserved_component_string()) */
|
||||
#define lv_is_component(lv) (lv_is_cache_origin(lv) || \
|
||||
lv_is_writecache_origin(lv) || \
|
||||
lv_is_integrity_origin(lv) || \
|
||||
((lv)->status & (\
|
||||
CACHE_POOL_DATA |\
|
||||
CACHE_POOL_METADATA |\
|
||||
INTEGRITY_METADATA |\
|
||||
LV_CACHE_VOL |\
|
||||
LV_VDO_POOL_DATA |\
|
||||
MIRROR_IMAGE |\
|
||||
@@ -1007,7 +1003,6 @@ struct lvcreate_params {
|
||||
const char *integrity_meta_name; /* external LV is user-specified */
|
||||
struct logical_volume *integrity_meta_lv; /* external LV we create */
|
||||
struct integrity_settings integrity_settings;
|
||||
uint64_t integrity_bytes_to_zero; /* zeros the final LV after it's created */
|
||||
|
||||
struct dm_list tags; /* all */
|
||||
|
||||
@@ -1103,8 +1098,6 @@ int lv_is_cache_origin(const struct logical_volume *lv);
|
||||
int lv_is_writecache_origin(const struct logical_volume *lv);
|
||||
int lv_is_writecache_cachevol(const struct logical_volume *lv);
|
||||
|
||||
int lv_is_integrity_origin(const struct logical_volume *lv);
|
||||
|
||||
int lv_is_merging_cow(const struct logical_volume *cow);
|
||||
uint32_t cow_max_extents(const struct logical_volume *origin, uint32_t chunk_size);
|
||||
int cow_has_min_chunks(const struct volume_group *vg, uint32_t cow_extents, uint32_t chunk_size);
|
||||
@@ -1406,13 +1399,10 @@ void vg_write_commit_bad_mdas(struct cmd_context *cmd, struct volume_group *vg);
|
||||
|
||||
int lv_add_integrity(struct logical_volume *lv, const char *arg,
|
||||
struct logical_volume *meta_lv_created,
|
||||
const char *meta_name, struct integrity_settings *settings,
|
||||
struct dm_list *pvh);
|
||||
const char *meta_name, struct integrity_settings *settings);
|
||||
int lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
struct volume_group *vg,
|
||||
struct lvcreate_params *lp);
|
||||
int lv_remove_integrity(struct logical_volume *lv);
|
||||
|
||||
int zero_lv_name(struct cmd_context *cmd, const char *vg_name, const char *lv_name, uint64_t zero_bytes);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -757,14 +757,6 @@ FLAGS: SECONDARY_SYNTAX
|
||||
|
||||
---
|
||||
|
||||
lvconvert --integrity String LV
|
||||
OO: OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_integrity
|
||||
DESC: Remove integrity from an LV.
|
||||
|
||||
---
|
||||
|
||||
# --extents is not specified; it's an automatic alternative for --size
|
||||
|
||||
OO_LVCREATE: --addtag Tag, --alloc Alloc, --autobackup Bool, --activate Active,
|
||||
@@ -878,8 +870,7 @@ DESC: Create a raid1 or mirror LV (infers --type raid1|mirror).
|
||||
# R9,R10,R11,R12 (--type raid with any use of --stripes/--mirrors)
|
||||
lvcreate --type raid --size SizeMB VG
|
||||
OO: --mirrors PNumber, --stripes Number, --stripesize SizeKB,
|
||||
--regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
|
||||
--integrity String, --integritysettings String, OO_LVCREATE
|
||||
--regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB, OO_LVCREATE
|
||||
OP: PV ...
|
||||
ID: lvcreate_raid_any
|
||||
DESC: Create a raid LV (a specific raid level must be used, e.g. raid1).
|
||||
|
||||
@@ -5730,75 +5730,6 @@ int lvconvert_to_cache_with_cachevol_cmd(struct cmd_context *cmd, int argc, char
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _lvconvert_integrity_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
struct volume_group *vg = lv->vg;
|
||||
struct lv_segment *seg;
|
||||
const char *arg = arg_str_value(cmd, integrity_ARG, NULL);
|
||||
|
||||
if (strcmp(arg, "none") && strcmp(arg, "n")) {
|
||||
log_error("Integrity can only be removed from an existing LV (see --integrity none).");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!lv_is_integrity(lv)) {
|
||||
log_error("LV does not have integrity.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
seg = first_seg(lv);
|
||||
|
||||
if (!seg->integrity_meta_dev) {
|
||||
log_error("Internal integrity cannot be removed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/* TODO: lift this restriction */
|
||||
if (lv_info(cmd, lv, 1, NULL, 0, 0)) {
|
||||
log_error("LV must be inactive to remove integrity.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!archive(vg))
|
||||
return ECMD_FAILED;
|
||||
|
||||
if (!lv_remove_integrity(lv))
|
||||
return ECMD_FAILED;
|
||||
|
||||
if (!vg_write(vg) || !vg_commit(vg))
|
||||
return ECMD_FAILED;
|
||||
|
||||
backup(vg);
|
||||
|
||||
log_print_unless_silent("Logical volume %s has removed integrity.", display_lvname(lv));
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
int lvconvert_integrity_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct processing_handle *handle;
|
||||
struct lvconvert_result lr = { 0 };
|
||||
int ret;
|
||||
|
||||
if (!(handle = init_processing_handle(cmd, NULL))) {
|
||||
log_error("Failed to initialize processing handle.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
handle->custom_handle = &lr;
|
||||
|
||||
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.
|
||||
|
||||
@@ -848,8 +848,6 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||
poolmetadataspare_ARG
|
||||
|
||||
#define RAID_ARGS \
|
||||
integrity_ARG,\
|
||||
integritysettings_ARG,\
|
||||
maxrecoveryrate_ARG,\
|
||||
minrecoveryrate_ARG,\
|
||||
raidmaxrecoveryrate_ARG,\
|
||||
@@ -1222,7 +1220,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
if (seg_is_integrity(lp) || seg_is_raid(lp)) {
|
||||
if (seg_is_integrity(lp)) {
|
||||
if (!get_integrity_options(cmd, &lp->integrity_arg, &lp->integrity_meta_name, &lp->integrity_settings))
|
||||
return 0;
|
||||
}
|
||||
@@ -1584,13 +1582,6 @@ static int _check_zero_parameters(struct cmd_context *cmd, struct lvcreate_param
|
||||
if (seg_is_thin(lp))
|
||||
return 1;
|
||||
|
||||
if (seg_is_integrity(lp)) {
|
||||
if (lp->zero && !is_change_activating(lp->activate)) {
|
||||
log_error("Zeroing integrity is not compatible with inactive creation (-an).");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is some problem, buffer will not be empty */
|
||||
if (dm_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
|
||||
lp->origin_name ? "origin " : "",
|
||||
@@ -1809,13 +1800,5 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
_destroy_lvcreate_params(&lp);
|
||||
destroy_processing_handle(cmd, handle);
|
||||
|
||||
if (lp.integrity_bytes_to_zero) {
|
||||
if (!lp.zero)
|
||||
log_warn("WARNING: not zeroing integrity LV, read errors are possible.");
|
||||
else
|
||||
zero_lv_name(cmd, lp.vg_name, lp.lv_name, lp.integrity_bytes_to_zero);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -149,9 +149,6 @@ static const struct command_function _command_functions[CMD_COUNT] = {
|
||||
{ lvconvert_to_vdopool_CMD, lvconvert_to_vdopool_cmd },
|
||||
{ lvconvert_to_vdopool_param_CMD, lvconvert_to_vdopool_param_cmd },
|
||||
|
||||
/* lvconvert for integrity */
|
||||
{ lvconvert_integrity_CMD, lvconvert_integrity_cmd },
|
||||
|
||||
{ pvscan_display_CMD, pvscan_display_cmd },
|
||||
{ pvscan_cache_CMD, pvscan_cache_cmd },
|
||||
};
|
||||
|
||||
@@ -275,8 +275,6 @@ int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_vdopool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_vdopool_param_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int lvconvert_integrity_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int pvscan_display_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user