mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-23 10:50:34 +03:00
lv_manip: rename set_lv -> wipe_lv and include signature wiping capability
Use common wipe_lv (former set_lv) fn to do zeroing as well as signature wiping if needed. Provide new struct wipe_lv_params to define the functionality. Bind "lvcreate -W/--wipesignatures y" with proper wipe_lv call. Also, add "yes" and "force" to lvcreate_params so it's possible to apply them for the prompt: "WARNING: %s detected on %s. Wipe it? [y/n]".
This commit is contained in:
parent
169b4c1586
commit
b6dab4e059
@ -2906,7 +2906,17 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
||||
* wipe '1' to remove the superblock of any previous
|
||||
* RAID devices. It is much quicker.
|
||||
*/
|
||||
if (!set_lv(meta_lv->vg->cmd, meta_lv, 1, 0)) {
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = meta_lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = 1,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
if (!wipe_lv(meta_lv->vg->cmd, &wp)) {
|
||||
log_error("Failed to zero %s/%s",
|
||||
meta_lv->vg->name, meta_lv->name);
|
||||
return 0;
|
||||
@ -5372,15 +5382,19 @@ int insert_layer_for_segments_on_pv(struct cmd_context *cmd,
|
||||
/*
|
||||
* Initialize the LV with 'value'.
|
||||
*/
|
||||
int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint64_t sectors, int value)
|
||||
int wipe_lv(struct cmd_context *cmd, struct wipe_lv_params *wp)
|
||||
{
|
||||
struct device *dev;
|
||||
char *name;
|
||||
uint64_t zero_sectors;
|
||||
|
||||
if (!lv_is_active_locally(lv)) {
|
||||
if (!(wp->do_zero || wp->do_wipe_signatures))
|
||||
/* nothing to do */
|
||||
return 1;
|
||||
|
||||
if (!lv_is_active_locally(wp->lv)) {
|
||||
log_error("Volume \"%s/%s\" is not active locally.",
|
||||
lv->vg->name, lv->name);
|
||||
wp->lv->vg->name, wp->lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5397,15 +5411,13 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
}
|
||||
|
||||
if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
|
||||
lv->vg->name, lv->name) < 0) {
|
||||
log_error("Name too long - device not cleared (%s)", lv->name);
|
||||
wp->lv->vg->name, wp->lv->name) < 0) {
|
||||
log_error("Name too long - device not cleared (%s)", wp->lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sync_local_dev_names(cmd); /* Wait until devices are available */
|
||||
|
||||
log_verbose("Clearing start of logical volume \"%s\"", lv->name);
|
||||
|
||||
if (!(dev = dev_cache_get(name, NULL))) {
|
||||
log_error("%s: not found: device not cleared", name);
|
||||
return 0;
|
||||
@ -5414,21 +5426,32 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (!dev_open_quiet(dev))
|
||||
return_0;
|
||||
|
||||
if (!sectors)
|
||||
sectors = UINT64_C(4096) >> SECTOR_SHIFT;
|
||||
if (wp->do_wipe_signatures) {
|
||||
log_verbose("Wiping known signatures on logical volume \"%s/%s\"",
|
||||
wp->lv->vg->name, wp->lv->name);
|
||||
if (!wipe_known_sbs(dev, name, wp->yes, wp->force))
|
||||
stack;
|
||||
}
|
||||
|
||||
if (sectors > lv->size)
|
||||
sectors = lv->size;
|
||||
if (wp->do_zero) {
|
||||
zero_sectors = wp->zero_sectors ? : UINT64_C(4096) >> SECTOR_SHIFT;
|
||||
|
||||
if (!dev_set(dev, UINT64_C(0), (size_t) sectors << SECTOR_SHIFT, value))
|
||||
stack;
|
||||
if (zero_sectors > wp->lv->size)
|
||||
zero_sectors = wp->lv->size;
|
||||
|
||||
log_verbose("Clearing start of logical volume \"%s/%s\"",
|
||||
wp->lv->vg->name, wp->lv->name);
|
||||
|
||||
if (!dev_set(dev, UINT64_C(0), (size_t) zero_sectors << SECTOR_SHIFT, wp->zero_value))
|
||||
stack;
|
||||
}
|
||||
|
||||
dev_flush(dev);
|
||||
|
||||
if (!dev_close_immediate(dev))
|
||||
stack;
|
||||
|
||||
lv->status &= ~LV_NOSCAN;
|
||||
wp->lv->status &= ~LV_NOSCAN;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -5982,12 +6005,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
backup(vg);
|
||||
|
||||
if (test_mode()) {
|
||||
log_verbose("Test mode: Skipping activation and zeroing.");
|
||||
log_verbose("Test mode: Skipping activation, zeroing and signature wiping.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Do not scan this LV until properly zeroed. */
|
||||
if (lp->zero)
|
||||
/* Do not scan this LV until properly zeroed/wiped. */
|
||||
if (lp->zero | lp->wipe_signatures)
|
||||
lv->status |= LV_NOSCAN;
|
||||
|
||||
if (lp->temporary)
|
||||
@ -6056,21 +6079,36 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
}
|
||||
} else if (!lv_active_change(cmd, lv, lp->activate)) {
|
||||
log_error("Failed to activate new LV.");
|
||||
if (lp->zero)
|
||||
if (lp->zero || lp->wipe_signatures)
|
||||
goto deactivate_and_revert_new_lv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!seg_is_thin(lp) && !lp->zero && !lp->snapshot)
|
||||
log_warn("WARNING: \"%s\" not zeroed", lv->name);
|
||||
else if ((!seg_is_thin(lp) ||
|
||||
(lv_is_thin_volume(lv) && !lp->snapshot &&
|
||||
!first_seg(first_seg(lv)->pool_lv)->zero_new_blocks)) &&
|
||||
!set_lv(cmd, lv, UINT64_C(0), 0)) {
|
||||
log_error("Aborting. Failed to wipe %s.",
|
||||
lp->snapshot ? "snapshot exception store" :
|
||||
"start of new LV");
|
||||
goto deactivate_and_revert_new_lv;
|
||||
if (!seg_is_thin(lp) && !lp->snapshot) {
|
||||
if (!lp->zero)
|
||||
log_warn("WARNING: \"%s/%s\" not zeroed", lv->vg->name, lv->name);
|
||||
if (!lp->wipe_signatures)
|
||||
log_verbose("Signature wiping on \"%s/%s\" not requested", lv->vg->name, lv->name);
|
||||
}
|
||||
|
||||
if ((!seg_is_thin(lp) ||
|
||||
(lv_is_thin_volume(lv) && !lp->snapshot &&
|
||||
!first_seg(first_seg(lv)->pool_lv)->zero_new_blocks))) {
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = lv,
|
||||
.do_zero = lp->zero,
|
||||
.zero_sectors = 0,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = lp->wipe_signatures,
|
||||
.yes = lp->yes,
|
||||
.force = lp->force
|
||||
};
|
||||
if (!wipe_lv(cmd, &wp)) {
|
||||
log_error("Aborting. Failed to wipe %s.",
|
||||
lp->snapshot ? "snapshot exception store" :
|
||||
"start of new LV");
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
}
|
||||
|
||||
if (lp->snapshot && !seg_is_thin(lp)) {
|
||||
|
@ -622,9 +622,18 @@ struct logical_volume *lv_create_empty(const char *name,
|
||||
alloc_policy_t alloc,
|
||||
struct volume_group *vg);
|
||||
|
||||
/* Write out LV contents */
|
||||
int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint64_t sectors, int value);
|
||||
struct wipe_lv_params {
|
||||
struct logical_volume *lv;
|
||||
int do_zero; /* should we do zeroing of LV start? */
|
||||
uint64_t zero_sectors; /* sector count to zero */
|
||||
int zero_value; /* zero-out with this value */
|
||||
int do_wipe_signatures; /* should we wipe known signatures found on LV? */
|
||||
int yes; /* answer yes automatically to all questions */
|
||||
force_t force; /* force mode */
|
||||
};
|
||||
|
||||
/* Zero out LV and/or wipe signatures */
|
||||
int wipe_lv(struct cmd_context *cmd, struct wipe_lv_params *params);
|
||||
|
||||
int lv_change_tag(struct logical_volume *lv, const char *tag, int add_tag);
|
||||
|
||||
@ -779,6 +788,9 @@ struct lvcreate_params {
|
||||
alloc_policy_t alloc; /* all */
|
||||
|
||||
struct dm_list tags; /* all */
|
||||
|
||||
int yes;
|
||||
force_t force;
|
||||
};
|
||||
|
||||
struct logical_volume *lv_create_single(struct volume_group *vg,
|
||||
|
@ -339,10 +339,20 @@ static int _init_mirror_log(struct cmd_context *cmd,
|
||||
dm_list_iterate_items(sl, tags)
|
||||
str_list_del(&log_lv->tags, sl->str);
|
||||
|
||||
if (activation() && !set_lv(cmd, log_lv, log_lv->size,
|
||||
in_sync ? -1 : 0)) {
|
||||
log_error("Aborting. Failed to wipe mirror log.");
|
||||
goto deactivate_and_revert_new_lv;
|
||||
if (activation()) {
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = log_lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = log_lv->size,
|
||||
.zero_value = in_sync ? -1 : 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
if (!wipe_lv(cmd, &wp)) {
|
||||
log_error("Aborting. Failed to wipe mirror log.");
|
||||
goto deactivate_and_revert_new_lv;
|
||||
}
|
||||
}
|
||||
|
||||
if (activation() && !_write_log_header(cmd, log_lv)) {
|
||||
|
@ -170,6 +170,15 @@ static int _raid_remove_top_layer(struct logical_volume *lv,
|
||||
static int _clear_lv(struct logical_volume *lv)
|
||||
{
|
||||
int was_active = lv_is_active_locally(lv);
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = 1,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
if (test_mode())
|
||||
return 1;
|
||||
@ -187,7 +196,7 @@ static int _clear_lv(struct logical_volume *lv)
|
||||
* wipe the first sector to remove the superblock of any previous
|
||||
* RAID devices. It is much quicker.
|
||||
*/
|
||||
if (!set_lv(lv->vg->cmd, lv, 1, 0)) {
|
||||
if (!wipe_lv(lv->vg->cmd, &wp)) {
|
||||
log_error("Failed to zero %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
@ -468,10 +468,20 @@ int create_pool(struct logical_volume *pool_lv, const struct segment_type *segty
|
||||
* FIXME: implement lazy clearing when activation is disabled
|
||||
*/
|
||||
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = pool_lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = 0,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
/* pool_lv is a new LV so the VG lock protects us */
|
||||
if (!activate_lv_local(pool_lv->vg->cmd, pool_lv) ||
|
||||
/* Clear 4KB of metadata device for new thin-pool. */
|
||||
!set_lv(pool_lv->vg->cmd, pool_lv, UINT64_C(0), 0)) {
|
||||
!wipe_lv(pool_lv->vg->cmd, &wp)) {
|
||||
log_error("Aborting. Failed to wipe pool metadata %s.",
|
||||
pool_lv->name);
|
||||
goto bad;
|
||||
|
@ -478,7 +478,18 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
log_very_verbose("Clearing %s device %s",
|
||||
(seg_is_raid(seg)) ? "metadata" : "log",
|
||||
lvl->lv->name);
|
||||
if (!set_lv(cmd, lvl->lv, lvl->lv->size, 0)) {
|
||||
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = lvl->lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = lvl->lv->size,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
if (!wipe_lv(cmd, &wp)) {
|
||||
log_error("Unable to reset sync status for %s",
|
||||
lv->name);
|
||||
if (!deactivate_lv(cmd, lvl->lv))
|
||||
|
@ -1846,10 +1846,22 @@ static int lvconvert_snapshot(struct cmd_context *cmd,
|
||||
|
||||
if (!lp->zero || !(lv->status & LVM_WRITE))
|
||||
log_warn("WARNING: \"%s\" not zeroed", lv->name);
|
||||
else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
|
||||
else {
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = 0,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
if (!wipe_lv(cmd, &wp)) {
|
||||
log_error("Aborting. Failed to wipe snapshot "
|
||||
"exception store.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!deactivate_lv(cmd, lv)) {
|
||||
@ -2463,7 +2475,18 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
|
||||
log_error("Aborting. Failed to activate thin metadata lv.");
|
||||
return 0;
|
||||
}
|
||||
if (!set_lv(cmd, metadata_lv, UINT64_C(0), 0)) {
|
||||
|
||||
struct wipe_lv_params wp = {
|
||||
.lv = metadata_lv,
|
||||
.do_zero = 1,
|
||||
.zero_sectors = 0,
|
||||
.zero_value = 0,
|
||||
.do_wipe_signatures = 0,
|
||||
.yes = 0,
|
||||
.force = PROMPT
|
||||
};
|
||||
|
||||
if (!wipe_lv(cmd, &wp)) {
|
||||
log_error("Aborting. Failed to wipe thin metadata lv.");
|
||||
return 0;
|
||||
}
|
||||
|
@ -710,6 +710,8 @@ static int _read_activation_params(struct lvcreate_params *lp, struct cmd_contex
|
||||
return 0;
|
||||
}
|
||||
|
||||
lp->yes = arg_count(cmd, yes_ARG);
|
||||
lp->force = (force_t) arg_count(cmd, force_ARG);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user