1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

activation: support activation of component LVs

Occasionaly users may need to peek into 'component devices.
Normally lvm2 does not let users activation component.

This patch adds special mode where user can activate
component LV in a 'read-only' mode i.e.:

lvchange -ay vg/pool_tdata

All devices can be deactivated with:

lvchange -an vg  |  vgchange -an....
This commit is contained in:
Zdenek Kabelac 2018-02-28 17:16:17 +01:00
parent 6134a71a90
commit 112846ce0b
7 changed files with 50 additions and 4 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
Support activation of component LVs in read-only mode.
Extend internal library to recognize and work with component LV.
Skip duplicate check for active LV when prompting for its removal.
Activate correct lock holding LV when it is cached.

View File

@ -2673,7 +2673,11 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
goto out;
}
if (filter)
/* Component LV activation is enforced to be 'read-only' */
/* TODO: should not apply for LVs in maintenance mode */
if (!lv_is_visible(lv) && lv_is_component(lv)) {
laopts->read_only = 1;
} else if (filter)
laopts->read_only = _passes_readonly_filter(cmd, lv);
log_debug_activation("Activating %s%s%s%s%s.", display_lvname(lv),

View File

@ -166,6 +166,8 @@ struct cmd_context {
unsigned lv_notify:1;
unsigned pv_notify:1;
unsigned use_aio:1;
unsigned activate_component:1; /* command activates component LV */
unsigned process_component_lvs:1; /* command processes also component LVs */
/*
* Filtering.

View File

@ -252,6 +252,7 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource,
uint32_t lck_type = flags & LCK_TYPE_MASK;
uint32_t lck_scope = flags & LCK_SCOPE_MASK;
int ret = 0;
const struct logical_volume *active_lv;
block_signals(flags);
_lock_memory(cmd, lv_op);
@ -268,6 +269,16 @@ static int _lock_vol(struct cmd_context *cmd, const char *resource,
goto out;
}
/* When trying activating component LV, make sure none of
* sub component LV or LVs that are using it are active */
if (lv && ((lck_type == LCK_READ) || (lck_type == LCK_EXCL)) &&
((!lv_is_visible(lv) && (active_lv = lv_holder_is_active(lv))) ||
(active_lv = lv_component_is_active(lv)))) {
log_error("Activation of logical volume %s is prohibited while logical volume %s is active.",
display_lvname(lv), display_lvname(active_lv));
goto out;
}
if (cmd->metadata_read_only && lck_type == LCK_WRITE &&
strcmp(resource, VG_GLOBAL)) {
log_error("Operation prohibited while global/metadata_read_only is set.");

View File

@ -1266,6 +1266,11 @@ int lvchange_properties_cmd(struct cmd_context *cmd, int argc, char **argv)
{
int ret;
if (cmd->activate_component) {
log_error("Cannot change LV properties when activating component LVs.");
return 0;
}
/*
* A command def rule allows only some options when LV is partial,
* so handles_missing_pvs will only affect those.
@ -1362,7 +1367,10 @@ static int _lvchange_activate_check(struct cmd_context *cmd,
struct processing_handle *handle,
int lv_is_named_arg)
{
if (!lv_is_visible(lv)) {
if (!lv_is_visible(lv) &&
!cmd->activate_component && /* activation of named component LV */
((first_seg(lv)->status & MERGING) || /* merging already started */
!cmd->process_component_lvs)) { /* deactivation of a component LV */
if (lv_is_named_arg)
log_error("Operation not permitted on hidden LV %s.", display_lvname(lv));
return 0;
@ -1391,6 +1399,23 @@ int lvchange_activate_cmd(struct cmd_context *cmd, int argc, char **argv)
if (do_activate)
cmd->lockd_vg_enforce_sh = 1;
/* When activating, check if given LV is a component LV */
if (do_activate) {
if ((argc == 1) && is_component_lvname(argv[0])) {
/* With single arg with reserved name prompt for component activation */
if (arg_is_set(cmd, yes_ARG) ||
(yes_no_prompt("Do you want to activate component LV "
"in read-only mode? [y/n]: ") == 'y')) {
log_print_unless_silent("Allowing activation of component LV.");
cmd->activate_component = 1;
}
if (sigint_caught())
return_ECMD_FAILED;
}
} else /* Component LVs might be active, support easy deactivation */
cmd->process_component_lvs = 1;
ret = process_each_lv(cmd, argc, argv, NULL, NULL, 0,
NULL, &_lvchange_activate_check, &_lvchange_activate_single);

View File

@ -3058,7 +3058,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
* Only let hidden LVs through if --all was used or the LVs
* were specifically named on the command line.
*/
if (!lvargs_supplied && !lv_is_visible(lvl->lv) && !arg_is_set(cmd, all_ARG))
if (!lvargs_supplied && !lv_is_visible(lvl->lv) && !arg_is_set(cmd, all_ARG) &&
(!cmd->process_component_lvs || !lv_is_component(lvl->lv)))
continue;
/*

View File

@ -92,7 +92,7 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd, struct volume_group *vg,
lv = lvl->lv;
if (!lv_is_visible(lv))
if (!lv_is_visible(lv) && (!cmd->process_component_lvs || !lv_is_component(lv)))
continue;
/* If LV is sparse, activate origin instead */
@ -222,6 +222,8 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
/* FIXME Move into library where clvmd can use it */
if (do_activate)
check_current_backup(vg);
else /* Component LVs might be active, support easy deactivation */
cmd->process_component_lvs = 1;
if (do_activate && (active = lvs_in_vg_activated(vg))) {
log_verbose("%d logical volume(s) in volume group \"%s\" "