2001-10-30 17:32:48 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2017-04-01 03:38:48 +03:00
* Copyright ( C ) 2004 - 2017 Red Hat , Inc . All rights reserved .
2001-10-30 17:32:48 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2001-10-30 17:32:48 +03:00
*
2004-03-30 23:35:44 +04:00
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2001-10-30 17:32:48 +03:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-10-30 17:32:48 +03:00
*/
# include "tools.h"
2015-07-06 19:30:18 +03:00
2018-05-14 12:30:20 +03:00
# include "lib/mm/memlock.h"
2001-10-30 17:32:48 +03:00
2017-04-01 03:38:48 +03:00
/*
* Passed back from callee to request caller to
2017-04-05 00:53:55 +03:00
* commit and optionally reload metadata .
2017-04-01 03:38:48 +03:00
*
* This allows for one metadata update per command run
* ( unless mandatory interim ones in callee ) .
*/
2017-04-05 00:53:55 +03:00
# define MR_COMMIT 0x1 /* Commit metadata, don't reload table(s) */
# define MR_RELOAD 0x2 /* Commit metadata _and_ reload table(s) */
2017-04-01 03:38:48 +03:00
static int _vg_write_commit ( const struct logical_volume * lv , const char * what )
{
2017-04-05 00:53:55 +03:00
log_very_verbose ( " Updating %s%slogical volume %s on disk(s). " ,
what ? : " " , what ? " " : " " , display_lvname ( lv ) ) ;
2017-04-01 03:38:48 +03:00
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) ) {
log_error ( " Failed to update %smetadata of %s on disk. " ,
what ? : " " , display_lvname ( lv ) ) ;
return 0 ;
}
return 1 ;
}
2015-02-26 21:38:26 +03:00
static int _lvchange_permission ( struct cmd_context * cmd ,
2017-04-01 03:38:48 +03:00
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2001-10-30 17:32:48 +03:00
{
2002-12-20 02:25:55 +03:00
uint32_t lv_access ;
2007-01-10 22:56:39 +03:00
struct lvinfo info ;
2001-10-30 17:32:48 +03:00
2002-12-20 02:25:55 +03:00
lv_access = arg_uint_value ( cmd , permission_ARG , 0 ) ;
2001-10-30 17:32:48 +03:00
if ( ! ( lv_access & LVM_WRITE ) & & ! ( lv - > status & LVM_WRITE ) ) {
2015-02-27 16:38:26 +03:00
/* Refresh if it's read-only in metadata but read-write in kernel */
2016-06-30 11:45:58 +03:00
if ( lv_info ( cmd , lv , 0 , & info , 0 , 0 ) & & info . exists & & ! info . read_only ) {
log_print_unless_silent ( " Logical volume %s is already read-only. Refreshing kernel state. " ,
display_lvname ( lv ) ) ;
2015-02-27 16:38:26 +03:00
return lv_refresh ( cmd , lv ) ;
}
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume \" %s \" is already read only. " ,
display_lvname ( lv ) ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
2015-02-26 21:38:26 +03:00
if ( ( lv_access & LVM_WRITE ) & & ( lv - > status & LVM_WRITE ) ) {
/* Refresh if it's read-write in metadata but read-only in kernel */
2016-06-30 11:45:58 +03:00
if ( lv_info ( cmd , lv , 0 , & info , 0 , 0 ) & & info . exists & & info . read_only ) {
log_print_unless_silent ( " Logical volume %s is already writable. Refreshing kernel state. " ,
display_lvname ( lv ) ) ;
2015-02-26 21:38:26 +03:00
return lv_refresh ( cmd , lv ) ;
}
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume %s is already writable. " ,
display_lvname ( lv ) ) ;
2013-02-05 17:03:43 +04:00
return 0 ;
}
2001-10-30 17:32:48 +03:00
if ( lv_access & LVM_WRITE ) {
lv - > status | = LVM_WRITE ;
2016-06-30 11:45:58 +03:00
log_verbose ( " Setting logical volume %s read/write. " ,
display_lvname ( lv ) ) ;
2001-10-30 17:32:48 +03:00
} else {
lv - > status & = ~ LVM_WRITE ;
2016-06-30 11:45:58 +03:00
log_verbose ( " Setting logical volume %s read-only. " ,
display_lvname ( lv ) ) ;
2001-10-30 17:32:48 +03:00
}
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2003-07-05 02:34:56 +04:00
2014-09-09 16:40:32 +04:00
return 1 ;
2001-10-30 17:32:48 +03:00
}
2015-02-26 21:38:26 +03:00
static int _lvchange_pool_update ( struct cmd_context * cmd ,
2017-04-01 03:38:48 +03:00
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2012-06-28 16:52:23 +04:00
{
int update = 0 ;
unsigned val ;
2012-08-08 00:24:41 +04:00
thin_discards_t discards ;
2012-06-28 16:52:23 +04:00
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( cmd , discards_ARG ) ) {
2012-08-21 17:51:54 +04:00
discards = ( thin_discards_t ) arg_uint_value ( cmd , discards_ARG , THIN_DISCARDS_IGNORE ) ;
2012-08-08 00:24:41 +04:00
if ( discards ! = first_seg ( lv ) - > discards ) {
2012-12-02 19:30:45 +04:00
if ( ( ( discards = = THIN_DISCARDS_IGNORE ) | |
2012-08-08 00:24:41 +04:00
( first_seg ( lv ) - > discards = = THIN_DISCARDS_IGNORE ) ) & &
2013-02-05 19:49:09 +04:00
pool_is_active ( lv ) )
2016-06-30 11:45:58 +03:00
log_error ( " Cannot change support for discards while pool volume %s is active. " ,
display_lvname ( lv ) ) ;
2012-06-28 16:52:23 +04:00
else {
2012-08-08 00:24:41 +04:00
first_seg ( lv ) - > discards = discards ;
2012-06-28 16:52:23 +04:00
update + + ;
}
} else
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume %s already uses --discards %s. " ,
display_lvname ( lv ) , get_pool_discards_name ( discards ) ) ;
2012-06-28 16:52:23 +04:00
}
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( cmd , zero_ARG ) ) {
2017-03-03 22:46:13 +03:00
val = arg_uint_value ( cmd , zero_ARG , 0 ) ? THIN_ZERO_YES : THIN_ZERO_NO ;
2012-06-28 16:52:23 +04:00
if ( val ! = first_seg ( lv ) - > zero_new_blocks ) {
first_seg ( lv ) - > zero_new_blocks = val ;
update + + ;
} else
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume %s already %szero new blocks. " ,
display_lvname ( lv ) , val ? " " : " does not " ) ;
2012-06-28 16:52:23 +04:00
}
if ( ! update )
return 0 ;
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2014-09-09 16:40:32 +04:00
return 1 ;
2012-06-28 16:52:23 +04:00
}
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
/*
2017-04-04 23:32:08 +03:00
* The - - monitor y | n value is read from dmeventd_monitor_mode ( ) ,
* which was set by the init_dmeventd_monitor ( ) /
* get_activation_monitoring_mode ( ) / arg_int_value ( monitor_ARG ) .
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
*/
2015-02-26 21:38:26 +03:00
static int _lvchange_monitoring ( struct cmd_context * cmd ,
struct logical_volume * lv )
2006-05-12 23:16:48 +04:00
{
struct lvinfo info ;
2012-03-23 13:58:04 +04:00
if ( ! lv_info ( cmd , lv , lv_is_thin_pool ( lv ) ? 1 : 0 ,
& info , 0 , 0 ) | | ! info . exists ) {
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume %s is not active. " , display_lvname ( lv ) ) ;
2006-05-12 23:16:48 +04:00
return 0 ;
}
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
if ( dmeventd_monitor_mode ( ) ! = DMEVENTD_MONITOR_IGNORE ) {
2017-04-04 23:32:08 +03:00
if ( dmeventd_monitor_mode ( ) )
log_verbose ( " Monitoring LV %s " , display_lvname ( lv ) ) ;
else
log_verbose ( " Unmonitoring LV %s " , display_lvname ( lv ) ) ;
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
if ( ! monitor_dev_for_events ( cmd , lv , 0 , dmeventd_monitor_mode ( ) ) )
return_0 ;
}
2006-05-12 23:16:48 +04:00
2007-01-20 01:21:45 +03:00
return 1 ;
2006-05-12 23:16:48 +04:00
}
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
/*
2017-04-04 23:32:08 +03:00
* The - - poll y | n value is read from background_polling ( ) ,
* which was set by init_background_polling ( arg_int_value ( poll_ARG ) ) .
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
*/
2015-02-26 21:38:26 +03:00
static int _lvchange_background_polling ( struct cmd_context * cmd ,
struct logical_volume * lv )
2010-01-05 23:56:51 +03:00
{
struct lvinfo info ;
2010-08-17 20:25:32 +04:00
if ( ! lv_info ( cmd , lv , 0 , & info , 0 , 0 ) | | ! info . exists ) {
2016-06-30 11:45:58 +03:00
log_error ( " Logical volume %s is not active. " , display_lvname ( lv ) ) ;
2010-01-05 23:56:51 +03:00
return 0 ;
}
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
if ( background_polling ( ) ) {
log_verbose ( " Polling LV %s " , display_lvname ( lv ) ) ;
2010-01-05 23:56:51 +03:00
lv_spawn_background_polling ( cmd , lv ) ;
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
}
2010-01-05 23:56:51 +03:00
return 1 ;
}
2012-06-27 15:48:31 +04:00
static int _lvchange_activate ( struct cmd_context * cmd , struct logical_volume * lv )
2001-10-30 17:32:48 +03:00
{
2013-04-21 14:49:58 +04:00
activation_change_t activate ;
2001-10-30 17:32:48 +03:00
2013-04-21 14:49:58 +04:00
activate = ( activation_change_t ) arg_uint_value ( cmd , activate_ARG , CHANGE_AY ) ;
2001-10-30 17:32:48 +03:00
2015-02-25 20:33:11 +03:00
/*
* We can get here in the odd case where an LV is already active in
* a foreign VG , which allows the VG to be accessed by lvchange - a
* so the LV can be deactivated .
*/
2015-03-04 01:45:16 +03:00
if ( lv - > vg - > system_id & & lv - > vg - > system_id [ 0 ] & &
cmd - > system_id & & cmd - > system_id [ 0 ] & &
2015-02-25 20:33:11 +03:00
strcmp ( lv - > vg - > system_id , cmd - > system_id ) & &
is_change_activating ( activate ) ) {
log_error ( " Cannot activate LVs in a foreign VG. " ) ;
return ECMD_FAILED ;
}
2016-06-22 00:24:52 +03:00
if ( lv_activation_skip ( lv , activate , arg_is_set ( cmd , ignoreactivationskip_ARG ) ) )
2013-07-11 14:44:36 +04:00
return 1 ;
2011-11-18 23:22:49 +04:00
if ( lv_is_cow ( lv ) & & ! lv_is_virtual_origin ( origin_from_cow ( lv ) ) )
lv = origin_from_cow ( lv ) ;
2013-04-11 15:51:08 +04:00
if ( ( activate = = CHANGE_AAY ) & &
! lv_passes_auto_activation_filter ( cmd , lv ) )
return 1 ;
2012-06-27 18:43:20 +04:00
2013-04-11 15:51:08 +04:00
if ( ! lv_change_activate ( cmd , lv , activate ) )
return_0 ;
2002-01-08 01:36:12 +03:00
2015-04-08 13:05:14 +03:00
/*
* FIXME : lvchange should defer background polling in a similar
* way as vgchange does . First activate all relevant LVs
* initate background polling later ( for all actually
* activated LVs ) . So we can avoid duplicate background
* polling for pvmove ( 2 or more locked LVs on single pvmove
* LV )
*/
if ( background_polling ( ) & & is_change_activating ( activate ) & &
( lv_is_pvmove ( lv ) | | lv_is_locked ( lv ) | | lv_is_converting ( lv ) | |
lv_is_merging ( lv ) ) )
lv_spawn_background_polling ( cmd , lv ) ;
2001-10-30 17:32:48 +03:00
return 1 ;
}
2017-10-18 17:57:46 +03:00
static int _detach_metadata_devices ( struct lv_segment * seg , struct dm_list * list )
2012-09-11 22:01:05 +04:00
{
2012-09-11 22:09:35 +04:00
uint32_t s ;
uint32_t num_meta_lvs ;
2012-09-11 22:01:05 +04:00
struct lv_list * lvl ;
2012-09-11 22:09:35 +04:00
num_meta_lvs = seg_is_raid ( seg ) ? seg - > area_count : ! ! seg - > log_lv ;
if ( ! num_meta_lvs )
return_0 ;
2012-09-11 22:01:05 +04:00
2013-04-25 12:15:13 +04:00
if ( ! ( lvl = dm_pool_alloc ( seg - > lv - > vg - > vgmem , sizeof ( * lvl ) * num_meta_lvs ) ) )
2012-09-11 22:01:05 +04:00
return_0 ;
2016-05-24 00:55:13 +03:00
if ( seg_is_raid_with_meta ( seg ) ) {
2012-09-11 22:09:35 +04:00
for ( s = 0 ; s < seg - > area_count ; s + + ) {
if ( ! seg_metalv ( seg , s ) )
return_0 ; /* Trap this future possibility */
lvl [ s ] . lv = seg_metalv ( seg , s ) ;
lv_set_visible ( lvl [ s ] . lv ) ;
dm_list_add ( list , & lvl [ s ] . list ) ;
}
return 1 ;
}
lvl [ 0 ] . lv = detach_mirror_log ( seg ) ;
dm_list_add ( list , & lvl [ 0 ] . list ) ;
2012-09-11 22:01:05 +04:00
return 1 ;
}
2017-10-18 17:57:46 +03:00
static int _attach_metadata_devices ( struct lv_segment * seg , struct dm_list * list )
2012-09-11 22:01:05 +04:00
{
2013-04-23 16:06:40 +04:00
struct lv_list * lvl ;
2012-09-11 22:01:05 +04:00
if ( seg_is_raid ( seg ) ) {
2013-04-23 16:06:40 +04:00
dm_list_iterate_items ( lvl , list )
2012-09-11 22:09:35 +04:00
lv_set_hidden ( lvl - > lv ) ;
return 1 ;
2012-09-11 22:01:05 +04:00
}
dm_list_iterate_items ( lvl , list )
break ; /* get first item */
2013-04-23 16:06:40 +04:00
if ( ! attach_mirror_log ( seg , lvl - > lv ) )
2012-09-11 22:01:05 +04:00
return_0 ;
return 1 ;
}
2013-09-11 01:33:22 +04:00
static int _reactivate_lv ( struct logical_volume * lv ,
int active , int exclusive )
{
struct cmd_context * cmd = lv - > vg - > cmd ;
if ( ! active )
return 1 ;
return activate_lv ( cmd , lv ) ;
}
2013-04-12 00:33:59 +04:00
/*
* lvchange_resync
* @ cmd
* @ lv
*
* Force a mirror or RAID array to undergo a complete initializing resync .
*/
2015-02-26 21:38:26 +03:00
static int _lvchange_resync ( struct cmd_context * cmd , struct logical_volume * lv )
2006-10-24 03:03:55 +04:00
{
int active = 0 ;
2013-09-11 01:33:22 +04:00
int exclusive = 0 ;
2008-05-21 18:10:11 +04:00
int monitored ;
2012-09-11 22:01:05 +04:00
struct lv_segment * seg = first_seg ( lv ) ;
struct dm_list device_list ;
struct lv_list * lvl ;
dm_list_init ( & device_list ) ;
2006-10-24 03:03:55 +04:00
2018-06-05 21:21:28 +03:00
if ( lv_is_active ( lv ) ) {
2016-04-22 00:14:10 +03:00
if ( ! lv_check_not_in_use ( lv , 1 ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Can't resync open logical volume %s. " ,
display_lvname ( lv ) ) ;
2009-05-20 13:55:33 +04:00
return 0 ;
2006-10-24 03:03:55 +04:00
}
2016-06-22 00:24:52 +03:00
if ( ! arg_is_set ( cmd , yes_ARG ) & &
2014-09-24 18:27:35 +04:00
yes_no_prompt ( " Do you really want to deactivate "
" logical volume %s to resync it? [y/n]: " ,
2016-06-30 11:45:58 +03:00
display_lvname ( lv ) ) = = ' n ' ) {
log_error ( " Logical volume %s not resynced. " ,
display_lvname ( lv ) ) ;
2014-09-24 18:27:35 +04:00
return 0 ;
2006-10-24 19:30:33 +04:00
}
2014-09-24 18:27:35 +04:00
active = 1 ;
2018-06-05 21:21:28 +03:00
if ( lv_is_active ( lv ) )
2014-09-24 18:27:35 +04:00
exclusive = 1 ;
2006-10-24 03:03:55 +04:00
}
2013-09-11 01:33:22 +04:00
if ( seg_is_raid ( seg ) & & active & & ! exclusive ) {
2016-06-30 11:45:58 +03:00
log_error ( " RAID logical volume %s cannot be active remotely. " ,
display_lvname ( lv ) ) ;
2013-09-11 01:33:22 +04:00
return 0 ;
}
2008-05-21 18:10:11 +04:00
/* Activate exclusively to ensure no nodes still have LV active */
monitored = dmeventd_monitor_mode ( ) ;
2012-10-09 14:20:47 +04:00
if ( monitored ! = DMEVENTD_MONITOR_IGNORE )
init_dmeventd_monitor ( 0 ) ;
2008-05-21 18:10:11 +04:00
2006-10-24 03:03:55 +04:00
if ( ! deactivate_lv ( cmd , lv ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Unable to deactivate %s for resync. " , display_lvname ( lv ) ) ;
2006-10-24 03:03:55 +04:00
return 0 ;
}
2012-10-09 14:20:47 +04:00
if ( monitored ! = DMEVENTD_MONITOR_IGNORE )
init_dmeventd_monitor ( monitored ) ;
2012-09-11 22:09:35 +04:00
init_mirror_in_sync ( 0 ) ;
2008-05-21 18:10:11 +04:00
2016-06-30 11:45:58 +03:00
log_very_verbose ( " Starting resync of %s%s%s%s %s. " ,
2006-10-24 03:03:55 +04:00
( active ) ? " active " : " " ,
2008-04-10 21:09:32 +04:00
vg_is_clustered ( lv - > vg ) ? " clustered " : " " ,
2012-09-11 22:09:35 +04:00
( seg - > log_lv ) ? " disk-logged " :
seg_is_raid ( seg ) ? " " : " core-logged " ,
2016-06-30 11:45:58 +03:00
lvseg_name ( seg ) , display_lvname ( lv ) ) ;
2006-10-24 03:03:55 +04:00
/*
2012-09-11 22:01:05 +04:00
* If this mirror has a core log ( i . e . ! seg - > log_lv ) ,
2006-10-24 03:03:55 +04:00
* then simply deactivating / activating will cause
* it to reset the sync status . We only need to
* worry about persistent logs .
*/
2012-09-11 22:09:35 +04:00
if ( ! seg_is_raid ( seg ) & & ! seg - > log_lv ) {
2016-07-14 16:21:01 +03:00
if ( lv_is_not_synced ( lv ) ) {
2012-09-11 21:55:17 +04:00
lv - > status & = ~ LV_NOTSYNCED ;
2017-04-01 03:38:48 +03:00
if ( ! _vg_write_commit ( lv , NULL ) )
2012-09-11 21:55:17 +04:00
return 0 ;
}
2013-09-11 01:33:22 +04:00
if ( ! _reactivate_lv ( lv , active , exclusive ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Failed to reactivate %s to resynchronize mirror. " ,
display_lvname ( lv ) ) ;
2006-10-24 03:03:55 +04:00
return 0 ;
}
2012-09-11 21:55:17 +04:00
2006-10-24 03:03:55 +04:00
return 1 ;
}
2012-09-11 21:55:17 +04:00
/*
* Now we handle mirrors with log devices
*/
2011-03-29 16:51:57 +04:00
lv - > status & = ~ LV_NOTSYNCED ;
2006-10-24 03:03:55 +04:00
2012-09-11 22:01:05 +04:00
/* Separate mirror log or metadata devices so we can clear them */
2017-10-18 17:57:46 +03:00
if ( ! _detach_metadata_devices ( seg , & device_list ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Failed to clear %s %s for %s. " ,
2016-12-25 02:29:30 +03:00
lvseg_name ( seg ) , seg_is_raid ( seg ) ?
2016-06-30 11:45:58 +03:00
" metadata area " : " mirror log " , display_lvname ( lv ) ) ;
2012-09-11 22:01:05 +04:00
return 0 ;
}
2006-10-24 03:03:55 +04:00
2017-04-01 03:38:48 +03:00
if ( ! _vg_write_commit ( lv , " intermediate " ) ) {
2013-09-11 01:33:22 +04:00
if ( ! _reactivate_lv ( lv , active , exclusive ) )
2012-09-11 21:55:17 +04:00
stack ;
return 0 ;
}
2009-04-21 18:31:57 +04:00
2014-09-19 17:16:26 +04:00
/* No backup for intermediate metadata, so just unlock memory */
memlock_unlock ( lv - > vg - > cmd ) ;
2006-10-24 03:03:55 +04:00
2012-09-11 22:01:05 +04:00
dm_list_iterate_items ( lvl , & device_list ) {
2018-06-05 21:21:28 +03:00
if ( ! activate_lv ( cmd , lvl - > lv ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Unable to activate %s for %s clearing. " ,
display_lvname ( lvl - > lv ) , ( seg_is_raid ( seg ) ) ?
2013-09-11 01:33:22 +04:00
" metadata area " : " mirror log " ) ;
2012-09-11 22:01:05 +04:00
return 0 ;
}
2006-10-24 03:03:55 +04:00
2013-11-28 14:22:24 +04:00
if ( ! wipe_lv ( lvl - > lv , ( struct wipe_params )
{ . do_zero = 1 , . zero_sectors = lvl - > lv - > size } ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Unable to reset sync status for %s. " ,
display_lvname ( lv ) ) ;
2012-09-11 22:01:05 +04:00
if ( ! deactivate_lv ( cmd , lvl - > lv ) )
log_error ( " Failed to deactivate log LV after "
" wiping failed " ) ;
return 0 ;
}
if ( ! deactivate_lv ( cmd , lvl - > lv ) ) {
log_error ( " Unable to deactivate %s LV %s "
2016-06-30 11:45:58 +03:00
" after wiping for resync. " ,
2012-09-11 22:01:05 +04:00
( seg_is_raid ( seg ) ) ? " metadata " : " log " ,
2016-06-30 11:45:58 +03:00
display_lvname ( lvl - > lv ) ) ;
2012-09-11 22:01:05 +04:00
return 0 ;
}
2012-09-11 21:55:17 +04:00
}
2006-10-24 03:03:55 +04:00
2015-06-30 20:54:38 +03:00
/* Wait until devices are away */
if ( ! sync_local_dev_names ( lv - > vg - > cmd ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Failed to sync local devices after updating %s. " ,
2015-06-30 20:54:38 +03:00
display_lvname ( lv ) ) ;
return 0 ;
}
2014-09-19 17:16:26 +04:00
2012-09-11 22:01:05 +04:00
/* Put metadata sub-LVs back in place */
2017-10-18 17:57:46 +03:00
if ( ! _attach_metadata_devices ( seg , & device_list ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Failed to reattach %s device after clearing. " ,
2012-09-11 22:01:05 +04:00
( seg_is_raid ( seg ) ) ? " metadata " : " log " ) ;
2012-09-11 21:55:17 +04:00
return 0 ;
2006-10-24 03:03:55 +04:00
}
2017-04-01 03:38:48 +03:00
if ( ! _vg_write_commit ( lv , NULL ) )
2006-10-24 03:03:55 +04:00
return 0 ;
2013-09-11 01:33:22 +04:00
if ( ! _reactivate_lv ( lv , active , exclusive ) ) {
2014-09-19 17:16:26 +04:00
backup ( lv - > vg ) ;
2016-06-30 11:45:58 +03:00
log_error ( " Failed to reactivate %s after resync. " ,
display_lvname ( lv ) ) ;
2006-10-24 03:03:55 +04:00
return 0 ;
}
2014-09-19 17:16:26 +04:00
backup ( lv - > vg ) ;
2006-10-24 03:03:55 +04:00
return 1 ;
}
2017-04-01 03:38:48 +03:00
static int _lvchange_alloc ( struct cmd_context * cmd ,
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2001-10-30 17:32:48 +03:00
{
2014-10-11 20:17:46 +04:00
int want_contiguous = arg_int_value ( cmd , contiguous_ARG , 0 ) ;
alloc_policy_t alloc = ( alloc_policy_t )
arg_uint_value ( cmd , alloc_ARG , ( want_contiguous )
? ALLOC_CONTIGUOUS : ALLOC_INHERIT ) ;
2001-10-30 17:32:48 +03:00
2004-05-19 02:12:53 +04:00
if ( alloc = = lv - > alloc ) {
2016-06-30 11:45:58 +03:00
log_error ( " Allocation policy of logical volume %s is already %s. " ,
display_lvname ( lv ) , get_alloc_string ( alloc ) ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
2004-05-19 02:12:53 +04:00
lv - > alloc = alloc ;
2001-10-30 17:32:48 +03:00
2004-05-19 02:12:53 +04:00
/* FIXME If contiguous, check existing extents already are */
2001-10-30 17:32:48 +03:00
2016-06-30 11:45:58 +03:00
log_verbose ( " Setting contiguous allocation policy for %s to %s. " ,
display_lvname ( lv ) , get_alloc_string ( alloc ) ) ;
2001-10-30 17:32:48 +03:00
2016-06-30 11:45:58 +03:00
log_very_verbose ( " Updating logical volume %s on disk(s). " , display_lvname ( lv ) ) ;
2004-05-19 02:12:53 +04:00
2009-04-21 18:31:57 +04:00
/* No need to suspend LV for this change */
2003-07-05 02:34:56 +04:00
2017-04-05 00:53:55 +03:00
/* Request caller to commit metadata */
* mr | = MR_COMMIT ;
2003-07-05 02:34:56 +04:00
2001-10-30 17:32:48 +03:00
return 1 ;
}
2015-02-26 21:38:26 +03:00
static int _lvchange_errorwhenfull ( struct cmd_context * cmd ,
2017-04-01 03:38:48 +03:00
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2015-01-15 17:20:08 +03:00
{
unsigned ewf = arg_int_value ( cmd , errorwhenfull_ARG , 0 ) ;
if ( ewf = = lv_is_error_when_full ( lv ) ) {
log_error ( " Error when full is already %sset for %s. " ,
( ewf ) ? " " : " un " , display_lvname ( lv ) ) ;
return 0 ;
}
if ( ewf )
lv - > status | = LV_ERROR_WHEN_FULL ;
else
lv - > status & = ~ LV_ERROR_WHEN_FULL ;
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2015-01-15 17:20:08 +03:00
return 1 ;
}
2015-02-26 21:38:26 +03:00
static int _lvchange_readahead ( struct cmd_context * cmd ,
2017-04-01 03:38:48 +03:00
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2001-10-30 17:32:48 +03:00
{
2006-05-10 01:23:51 +04:00
unsigned read_ahead = 0 ;
2007-12-05 22:24:32 +03:00
unsigned pagesize = ( unsigned ) lvm_getpagesize ( ) > > SECTOR_SHIFT ;
2001-10-30 17:32:48 +03:00
2002-12-20 02:25:55 +03:00
read_ahead = arg_uint_value ( cmd , readahead_ARG , 0 ) ;
2001-10-30 17:32:48 +03:00
2007-11-09 19:51:54 +03:00
if ( read_ahead ! = DM_READ_AHEAD_AUTO & &
( lv - > vg - > fid - > fmt - > features & FMT_RESTRICTED_READAHEAD ) & &
( read_ahead < 2 | | read_ahead > 120 ) ) {
log_error ( " Metadata only supports readahead values between 2 and 120. " ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
2007-12-05 22:24:32 +03:00
if ( read_ahead ! = DM_READ_AHEAD_AUTO & &
read_ahead ! = DM_READ_AHEAD_NONE & & read_ahead % pagesize ) {
2009-06-07 02:00:20 +04:00
if ( read_ahead < pagesize )
read_ahead = pagesize ;
else
read_ahead = ( read_ahead / pagesize ) * pagesize ;
log_warn ( " WARNING: Overriding readahead to %u sectors, a multiple "
" of %uK page size. " , read_ahead , pagesize > > 1 ) ;
2007-12-05 22:24:32 +03:00
}
2001-10-30 17:32:48 +03:00
if ( lv - > read_ahead = = read_ahead ) {
2008-06-18 15:32:14 +04:00
if ( read_ahead = = DM_READ_AHEAD_AUTO )
2016-06-30 11:45:58 +03:00
log_error ( " Read ahead is already auto for %s. " ,
display_lvname ( lv ) ) ;
2008-06-18 15:32:14 +04:00
else
2016-06-30 11:45:58 +03:00
log_error ( " Read ahead is already %u for %s. " ,
read_ahead , display_lvname ( lv ) ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
lv - > read_ahead = read_ahead ;
2002-02-21 00:30:27 +03:00
2016-06-30 11:45:58 +03:00
log_verbose ( " Setting read ahead to %u for %s. " ,
read_ahead , display_lvname ( lv ) ) ;
2001-10-30 17:32:48 +03:00
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2003-07-05 02:34:56 +04:00
2014-09-09 16:40:32 +04:00
return 1 ;
2001-10-30 17:32:48 +03:00
}
2002-02-01 20:54:39 +03:00
2015-02-26 21:38:26 +03:00
static int _lvchange_persistent ( struct cmd_context * cmd ,
2017-04-01 03:38:48 +03:00
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2002-02-01 20:54:39 +03:00
{
2014-09-19 16:57:02 +04:00
enum activation_change activate = CHANGE_AN ;
2015-03-05 23:00:44 +03:00
/* The LV lock in lvmlockd should remain as it is. */
cmd - > lockd_lv_disable = 1 ;
2014-09-27 20:53:08 +04:00
if ( ! get_and_validate_major_minor ( cmd , lv - > vg - > fid - > fmt ,
& lv - > major , & lv - > minor ) )
2014-09-19 16:57:02 +04:00
return_0 ;
2002-02-25 15:56:16 +03:00
2014-09-19 16:57:02 +04:00
if ( lv - > minor = = - 1 ) {
2002-02-01 20:54:39 +03:00
if ( ! ( lv - > status & FIXED_MINOR ) ) {
2014-09-19 16:57:02 +04:00
log_error ( " Minor number is already not persistent for %s. " ,
display_lvname ( lv ) ) ;
2002-02-01 20:54:39 +03:00
return 0 ;
}
lv - > status & = ~ FIXED_MINOR ;
2014-09-19 16:57:02 +04:00
log_verbose ( " Disabling persistent device number for %s. " ,
display_lvname ( lv ) ) ;
2002-02-01 20:54:39 +03:00
} else {
2014-09-19 16:57:02 +04:00
if ( lv_is_active ( lv ) ) {
2016-06-22 00:24:52 +03:00
if ( ! arg_is_set ( cmd , force_ARG ) & &
! arg_is_set ( cmd , yes_ARG ) & &
2014-09-19 16:57:02 +04:00
yes_no_prompt ( " Logical volume %s will be "
" deactivated temporarily. "
2016-06-30 11:45:58 +03:00
" Continue? [y/n]: " ,
display_lvname ( lv ) ) = = ' n ' ) {
2014-09-19 16:57:02 +04:00
log_error ( " %s device number not changed. " ,
display_lvname ( lv ) ) ;
return 0 ;
}
2012-08-06 20:01:01 +04:00
2014-09-19 16:57:02 +04:00
activate = CHANGE_AEY ;
2003-07-11 21:10:19 +04:00
}
2007-06-15 14:11:14 +04:00
2014-09-19 16:57:02 +04:00
/* Ensuring LV is not active */
2005-08-15 16:00:04 +04:00
if ( ! deactivate_lv ( cmd , lv ) ) {
2014-09-19 16:57:02 +04:00
log_error ( " Cannot deactivate %s. " , display_lvname ( lv ) ) ;
2002-03-11 22:02:28 +03:00
return 0 ;
}
2002-02-01 20:54:39 +03:00
lv - > status | = FIXED_MINOR ;
2014-09-19 16:57:02 +04:00
log_verbose ( " Setting persistent device number to (%d, %d) for %s. " ,
lv - > major , lv - > minor , display_lvname ( lv ) ) ;
2002-02-01 20:54:39 +03:00
}
2017-04-01 03:38:48 +03:00
if ( ! _vg_write_commit ( lv , NULL ) )
return 0 ;
2003-07-05 02:34:56 +04:00
2014-09-19 16:57:02 +04:00
if ( activate ! = CHANGE_AN ) {
2016-06-30 11:45:58 +03:00
log_verbose ( " Re-activating logical volume %s. " , display_lvname ( lv ) ) ;
2018-06-05 21:21:28 +03:00
if ( ! lv_active_change ( cmd , lv , activate ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " %s: reactivation failed. " , display_lvname ( lv ) ) ;
2014-09-19 16:57:02 +04:00
backup ( lv - > vg ) ;
2006-07-10 23:39:14 +04:00
return 0 ;
}
2002-04-24 22:20:51 +04:00
}
2002-02-21 00:30:27 +03:00
2002-02-01 20:54:39 +03:00
return 1 ;
}
2002-11-18 17:04:08 +03:00
2017-04-01 03:38:48 +03:00
static int _lvchange_cache ( struct cmd_context * cmd ,
struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2014-11-19 20:39:58 +03:00
{
2017-02-26 22:18:37 +03:00
cache_metadata_format_t format ;
2016-04-25 14:39:30 +03:00
cache_mode_t mode ;
2015-07-15 12:06:40 +03:00
const char * name ;
struct dm_config_tree * settings = NULL ;
2016-04-25 14:39:30 +03:00
struct lv_segment * pool_seg = first_seg ( lv ) ;
int r = 0 , is_clean ;
2017-03-09 18:20:44 +03:00
uint32_t chunk_size = 0 ; /* FYI: lvchange does NOT support its change */
2016-04-25 14:39:30 +03:00
if ( lv_is_cache ( lv ) )
pool_seg = first_seg ( pool_seg - > pool_lv ) ;
2014-11-19 20:39:58 +03:00
2017-02-26 22:18:37 +03:00
if ( ! get_cache_params ( cmd , & chunk_size , & format , & mode , & name , & settings ) )
2016-04-25 14:39:30 +03:00
goto_out ;
2017-03-03 16:52:32 +03:00
if ( ( mode ! = CACHE_MODE_UNSELECTED ) & &
2016-05-25 17:27:12 +03:00
( mode ! = pool_seg - > cache_mode ) & &
lv_is_cache ( lv ) ) {
2016-04-25 14:39:30 +03:00
if ( ! lv_cache_wait_for_clean ( lv , & is_clean ) )
return_0 ;
if ( ! is_clean ) {
log_error ( " Cache %s is not clean, refusing to switch cache mode. " ,
display_lvname ( lv ) ) ;
return 0 ;
}
}
if ( mode & & ! cache_set_cache_mode ( first_seg ( lv ) , mode ) )
2014-11-19 20:39:58 +03:00
goto_out ;
2016-04-25 14:39:30 +03:00
if ( ( name | | settings ) & &
! cache_set_policy ( first_seg ( lv ) , name , settings ) )
2014-11-19 20:39:58 +03:00
goto_out ;
2016-04-25 14:39:30 +03:00
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2016-04-25 14:39:30 +03:00
2014-11-19 20:39:58 +03:00
r = 1 ;
out :
2015-07-15 12:06:40 +03:00
if ( settings )
dm_config_destroy ( settings ) ;
2014-11-19 20:39:58 +03:00
return r ;
}
2017-04-01 03:38:48 +03:00
static int _lvchange_tag ( struct cmd_context * cmd , struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
int arg , uint32_t * mr )
2004-03-08 20:19:15 +03:00
{
2011-01-24 16:38:31 +03:00
if ( ! change_tag ( cmd , NULL , lv , NULL , arg ) )
return_0 ;
2004-03-08 20:19:15 +03:00
2016-06-30 11:45:58 +03:00
log_very_verbose ( " Updating logical volume %s on disk(s). " , display_lvname ( lv ) ) ;
2004-03-08 20:19:15 +03:00
/* No need to suspend LV for this change */
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_COMMIT ;
2009-04-21 18:31:57 +04:00
2004-03-08 20:19:15 +03:00
return 1 ;
}
2005-03-22 01:55:12 +03:00
2016-08-05 16:54:49 +03:00
static int _lvchange_rebuild ( struct logical_volume * lv )
{
int pv_count , i = 0 ;
char * * rebuild_pvs ;
const char * tmp_str ;
struct dm_list * rebuild_pvh = NULL ;
struct arg_value_group_list * group ;
struct volume_group * vg = lv - > vg ;
struct cmd_context * cmd = vg - > cmd ;
if ( ! ( pv_count = arg_count ( cmd , rebuild_ARG ) ) ) {
log_error ( " No --rebuild found! " ) ;
return 0 ;
}
if ( ! arg_is_set ( cmd , yes_ARG ) & &
yes_no_prompt ( " Do you really want to rebuild %u PVs "
" of logical volume %s [y/n]: " ,
pv_count , display_lvname ( lv ) ) = = ' n ' ) {
log_error ( " Logical volume %s not rebuild. " ,
display_lvname ( lv ) ) ;
return 0 ;
}
/* rebuild can be specified more than once */
if ( ! ( rebuild_pvs = dm_pool_alloc ( vg - > vgmem , sizeof ( char * ) * pv_count ) ) )
return_0 ;
dm_list_iterate_items ( group , & cmd - > arg_value_groups ) {
if ( ! grouped_arg_is_set ( group - > arg_values , rebuild_ARG ) )
continue ;
if ( ! ( tmp_str = grouped_arg_str_value ( group - > arg_values ,
rebuild_ARG , NULL ) ) )
return_0 ;
if ( ! ( rebuild_pvs [ i + + ] = dm_pool_strdup ( cmd - > mem , tmp_str ) ) )
return_0 ;
}
if ( ! ( rebuild_pvh = create_pv_list ( cmd - > mem , vg ,
pv_count , rebuild_pvs , 0 ) ) )
return_ECMD_FAILED ;
/* Rebuild PVs listed on @rebuild_pvh */
return lv_raid_rebuild ( lv , rebuild_pvh ) ;
}
2017-04-01 03:38:48 +03:00
static int _lvchange_writemostly ( struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
{
2017-03-26 21:28:04 +03:00
int pv_count , i = 0 ;
uint32_t s , writemostly ;
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
char * * pv_names ;
const char * tmp_str ;
2013-07-19 23:37:43 +04:00
size_t tmp_str_len ;
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
struct pv_list * pvl ;
struct arg_value_group_list * group ;
struct cmd_context * cmd = lv - > vg - > cmd ;
struct lv_segment * raid_seg = first_seg ( lv ) ;
2017-02-23 17:09:29 +03:00
/*
* Prohibit writebehind and writebehind during synchronization .
*
* FIXME : we can do better once we can distingush between
* an initial sync after a linear - > raid1 upconversion
* and any later additions of legs , requested resyncs
* via lvchange or leg repairs / replacements .
*/
if ( ! lv_raid_in_sync ( lv ) ) {
log_error ( " Unable to change write%s on %s while it is not in-sync. " ,
arg_is_set ( cmd , writemostly_ARG ) ? " mostly " : " behind " ,
display_lvname ( lv ) ) ;
return 0 ;
}
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( cmd , writebehind_ARG ) )
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
raid_seg - > writebehind = arg_uint_value ( cmd , writebehind_ARG , 0 ) ;
2014-08-21 17:38:18 +04:00
if ( ( pv_count = arg_count ( cmd , writemostly_ARG ) ) ) {
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
/* writemostly can be specified more than once */
2013-04-25 12:15:13 +04:00
pv_names = dm_pool_alloc ( lv - > vg - > vgmem , sizeof ( char * ) * pv_count ) ;
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
if ( ! pv_names )
return_0 ;
dm_list_iterate_items ( group , & cmd - > arg_value_groups ) {
if ( ! grouped_arg_is_set ( group - > arg_values ,
writemostly_ARG ) )
continue ;
if ( ! ( tmp_str = grouped_arg_str_value ( group - > arg_values ,
writemostly_ARG ,
NULL ) ) )
return_0 ;
/*
* Writemostly PV specifications can be :
* < PV > - Turn on writemostly
* < PV > : t - Toggle writemostly
* < PV > : n - Turn off writemostly
* < PV > : y - Turn on writemostly
*
* We allocate strlen + 3 to add our own ' : { t | n | y } ' if
* not present plus the trailing ' \0 ' .
*/
2013-07-19 23:37:43 +04:00
tmp_str_len = strlen ( tmp_str ) ;
if ( ! ( pv_names [ i ] = dm_pool_zalloc ( lv - > vg - > vgmem , tmp_str_len + 3 ) ) )
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
return_0 ;
2013-10-24 07:44:04 +04:00
if ( ( tmp_str_len < 3 ) | |
( tmp_str [ tmp_str_len - 2 ] ! = ' : ' ) )
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
/* Default to 'y' if no mode specified */
sprintf ( pv_names [ i ] , " %s:y " , tmp_str ) ;
else
sprintf ( pv_names [ i ] , " %s " , tmp_str ) ;
i + + ;
}
for ( i = 0 ; i < pv_count ; i + + )
pv_names [ i ] [ strlen ( pv_names [ i ] ) - 2 ] = ' \0 ' ;
for ( i = 0 ; i < pv_count ; i + + ) {
if ( ! ( pvl = find_pv_in_vg ( lv - > vg , pv_names [ i ] ) ) ) {
log_error ( " %s not found in volume group, %s " ,
pv_names [ i ] , lv - > vg - > name ) ;
return 0 ;
}
2017-03-26 21:28:04 +03:00
for ( s = 0 ; s < raid_seg - > area_count ; s + + ) {
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
/*
* We don ' t bother checking the metadata area ,
* since writemostly only affects the data areas .
*/
2014-08-29 13:58:16 +04:00
if ( seg_type ( raid_seg , s ) = = AREA_UNASSIGNED )
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
continue ;
if ( lv_is_on_pv ( seg_lv ( raid_seg , s ) , pvl - > pv ) ) {
if ( pv_names [ i ] [ strlen ( pv_names [ i ] ) + 1 ] = = ' y ' )
seg_lv ( raid_seg , s ) - > status | =
LV_WRITEMOSTLY ;
else if ( pv_names [ i ] [ strlen ( pv_names [ i ] ) + 1 ] = = ' n ' )
seg_lv ( raid_seg , s ) - > status & =
~ LV_WRITEMOSTLY ;
else if ( pv_names [ i ] [ strlen ( pv_names [ i ] ) + 1 ] = = ' t ' )
seg_lv ( raid_seg , s ) - > status ^ =
LV_WRITEMOSTLY ;
else
return_0 ;
}
}
2017-03-26 21:28:04 +03:00
}
/* Only allow a maximum on N-1 images to be set writemostly. */
writemostly = 0 ;
for ( s = 0 ; s < raid_seg - > area_count ; s + + )
if ( seg_lv ( raid_seg , s ) - > status & LV_WRITEMOSTLY )
writemostly + + ;
if ( writemostly = = raid_seg - > area_count ) {
log_error ( " Can't set all images of %s LV %s to writemostly. " ,
lvseg_name ( raid_seg ) , display_lvname ( lv ) ) ;
return 0 ;
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
}
}
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
return 1 ;
}
2017-04-01 03:38:48 +03:00
static int _lvchange_recovery_rate ( struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2013-05-31 20:25:52 +04:00
{
struct cmd_context * cmd = lv - > vg - > cmd ;
struct lv_segment * raid_seg = first_seg ( lv ) ;
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( cmd , minrecoveryrate_ARG ) )
2013-05-31 20:25:52 +04:00
raid_seg - > min_recovery_rate =
2013-08-12 21:40:52 +04:00
arg_uint_value ( cmd , minrecoveryrate_ARG , 0 ) / 2 ;
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( cmd , maxrecoveryrate_ARG ) )
2013-05-31 20:25:52 +04:00
raid_seg - > max_recovery_rate =
2013-08-12 21:40:52 +04:00
arg_uint_value ( cmd , maxrecoveryrate_ARG , 0 ) / 2 ;
2013-05-31 20:25:52 +04:00
if ( raid_seg - > max_recovery_rate & &
( raid_seg - > max_recovery_rate < raid_seg - > min_recovery_rate ) ) {
2016-06-30 11:45:58 +03:00
log_error ( " Minimum recovery rate cannot be higher than maximum. " ) ;
2013-05-31 20:25:52 +04:00
return 0 ;
}
2017-04-05 00:53:55 +03:00
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
2013-05-31 20:25:52 +04:00
return 1 ;
}
2017-04-01 03:38:48 +03:00
static int _lvchange_profile ( struct logical_volume * lv ,
2017-04-05 00:53:55 +03:00
uint32_t * mr )
2013-06-25 14:33:06 +04:00
{
const char * old_profile_name , * new_profile_name ;
struct profile * new_profile ;
old_profile_name = lv - > profile ? lv - > profile - > name : " (inherited) " ;
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( lv - > vg - > cmd , detachprofile_ARG ) ) {
2013-06-25 14:33:06 +04:00
new_profile_name = " (inherited) " ;
lv - > profile = NULL ;
} else {
2016-06-22 00:24:52 +03:00
if ( arg_is_set ( lv - > vg - > cmd , metadataprofile_ARG ) )
config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
(before, it was just CONFIG_PROFILE that did not make the
difference between the two). This helps when checking the
configuration if it contains correct set of options which
are all in either command-profilable or metadata-profilable
group without mixing these groups together - so it's a firm
distinction. The "command profile" can't contain
"metadata profile" and vice versa! This is strictly checked
and if the settings are mixed, such profile is rejected and
it's not used. So in the end, the CONFIG_PROFILE_COMMAND
set of options and CONFIG_PROFILE_METADATA are mutually exclusive
sets.
- Marking configuration with one or the other marker will also
determine the way these configuration sources are positioned
in the configuration cascade which is now:
CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES
- Marking configuration with one or the other marker will also make
it possible to issue a command context refresh (will be probably
a part of a future patch) if needed for settings in global profile
set. For settings in metadata profile set this is impossible since
we can't refresh cmd context in the middle of reading VG/LV metadata
and for each VG/LV separately because each VG/LV can have a different
metadata profile assinged and it's not possible to change these
settings at this level.
- When command profile is incorrect, it's rejected *and also* the
command exits immediately - the profile *must* be correct for the
command that was run with a profile to be executed. Before this
patch, when the profile was found incorrect, there was just the
warning message and the command continued without profile applied.
But it's more correct to exit immediately in this case.
- When metadata profile is incorrect, we reject it during command
runtime (as we know the profile name from metadata and not early
from command line as it is in case of command profiles) and we
*do continue* with the command as we're in the middle of operation.
Also, the metadata profile is applied directly and on the fly on
find_config_tree_* fn call and even if the metadata profile is
found incorrect, we still need to return the non-profiled value
as found in the other configuration provided or default value.
To exit immediately even in this case, we'd need to refactor
existing find_config_tree_* fns so they can return error. Currently,
these fns return only config values (which end up with default
values in the end if the config is not found).
- To check the profile validity before use to be sure it's correct,
one can use :
lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate
(the --commandprofile/--metadataprofile for dumpconfig will come
as part of the subsequent patch)
- This patch also adds a reference to --commandprofile and
--metadataprofile in the cmd help string (which was missing before
for the --profile for some commands). We do not mention --profile
now as people should use --commandprofile or --metadataprofile
directly. However, the --profile is still supported for backward
compatibility and it's translated as:
--profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
(as these commands are able to attach profile to metadata)
--profile == --commandprofile for all the other commands
(--metadataprofile is not allowed there as it makes no sense)
- This patch also contains some cleanups to make the code handling
the profiles more readable...
2014-05-20 16:13:10 +04:00
new_profile_name = arg_str_value ( lv - > vg - > cmd , metadataprofile_ARG , NULL ) ;
else
new_profile_name = arg_str_value ( lv - > vg - > cmd , profile_ARG , NULL ) ;
if ( ! ( new_profile = add_profile ( lv - > vg - > cmd , new_profile_name , CONFIG_PROFILE_METADATA ) ) )
2013-06-25 14:33:06 +04:00
return_0 ;
lv - > profile = new_profile ;
}
log_verbose ( " Changing configuration profile for LV %s: %s -> %s. " ,
2016-06-30 11:45:58 +03:00
display_lvname ( lv ) , old_profile_name , new_profile_name ) ;
2013-06-25 14:33:06 +04:00
2017-04-05 00:53:55 +03:00
/* Request caller to commit metadata */
* mr | = MR_COMMIT ;
2013-07-11 14:25:10 +04:00
2013-06-25 14:33:06 +04:00
return 1 ;
}
2017-04-05 00:53:55 +03:00
static int _lvchange_activation_skip ( struct logical_volume * lv , uint32_t * mr )
2013-07-11 14:44:36 +04:00
{
int skip = arg_int_value ( lv - > vg - > cmd , setactivationskip_ARG , 0 ) ;
lv_set_activation_skip ( lv , 1 , skip ) ;
log_verbose ( " Changing activation skip flag to %s for LV %s. " ,
2016-06-30 11:45:58 +03:00
display_lvname ( lv ) , skip ? " enabled " : " disabled " ) ;
2013-07-11 14:44:36 +04:00
2017-04-01 03:38:48 +03:00
/* Request caller to commit+backup metadata */
2017-04-05 00:53:55 +03:00
* mr | = MR_COMMIT ;
2013-07-11 14:44:36 +04:00
2017-04-01 03:38:48 +03:00
return 1 ;
}
2018-07-02 11:51:45 +03:00
static int _lvchange_compression ( struct logical_volume * lv , uint32_t * mr )
{
struct cmd_context * cmd = lv - > vg - > cmd ;
unsigned compression = arg_uint_value ( cmd , compression_ARG , 0 ) ;
struct lv_segment * seg = first_seg ( lv ) ;
if ( lv_is_vdo ( lv ) )
seg = first_seg ( seg_lv ( seg , 0 ) ) ;
else if ( ! lv_is_vdo_pool ( lv ) ) {
log_error ( " Unable to change compression for non VDO volume %s. " ,
display_lvname ( lv ) ) ;
return 0 ;
}
if ( compression = = seg - > vdo_params . use_compression ) {
log_error ( " Logical volume %s already uses --compression %c. " ,
display_lvname ( lv ) , compression ? ' y ' : ' n ' ) ;
return 0 ;
}
seg - > vdo_params . use_compression = compression ;
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
return 1 ;
}
static int _lvchange_deduplication ( struct logical_volume * lv , uint32_t * mr )
{
struct cmd_context * cmd = lv - > vg - > cmd ;
unsigned deduplication = arg_uint_value ( cmd , deduplication_ARG , 0 ) ;
struct lv_segment * seg = first_seg ( lv ) ;
if ( lv_is_vdo ( lv ) )
seg = first_seg ( seg_lv ( seg , 0 ) ) ;
else if ( ! lv_is_vdo_pool ( lv ) ) {
log_error ( " Unable to change deduplication for non VDO volume %s. " ,
display_lvname ( lv ) ) ;
return 0 ;
}
if ( deduplication = = seg - > vdo_params . use_deduplication ) {
log_error ( " Logical volume %s already uses --deduplication %c. " ,
display_lvname ( lv ) , deduplication ? ' y ' : ' n ' ) ;
return 0 ;
}
seg - > vdo_params . use_deduplication = deduplication ;
/* Request caller to commit and reload metadata */
* mr | = MR_RELOAD ;
return 1 ;
}
2017-04-01 03:38:48 +03:00
/* Update and reload or commit and/or backup metadata for @lv as requested by @mr */
2017-04-05 00:53:55 +03:00
static int _commit_reload ( struct logical_volume * lv , uint32_t mr )
2017-04-01 03:38:48 +03:00
{
2017-04-05 00:53:55 +03:00
if ( mr & MR_RELOAD ) {
2017-04-01 03:38:48 +03:00
if ( ! lv_update_and_reload ( lv ) )
return_0 ;
} else if ( ( mr & MR_COMMIT ) & &
! _vg_write_commit ( lv , NULL ) )
return 0 ;
2013-07-11 14:44:36 +04:00
return 1 ;
}
2017-04-05 18:29:31 +03:00
/* Helper: check @opt_num is listed in @opts array */
static int _is_option_listed ( int opt_enum , int * options )
{
int i ;
for ( i = 0 ; options [ i ] ! = - 1 ; i + + )
if ( opt_enum = = options [ i ] )
return 1 ;
return 0 ;
}
/* Check @opt_enum is an option allowing group commit/reload */
static int _option_allows_group_commit ( int opt_enum )
{
int options [ ] = {
permission_ARG ,
alloc_ARG ,
contiguous_ARG ,
2018-07-02 11:51:45 +03:00
compression_ARG ,
deduplication_ARG ,
2017-04-05 18:29:31 +03:00
errorwhenfull_ARG ,
readahead_ARG ,
persistent_ARG ,
addtag_ARG ,
deltag_ARG ,
writemostly_ARG ,
writebehind_ARG ,
minrecoveryrate_ARG ,
maxrecoveryrate_ARG ,
profile_ARG ,
metadataprofile_ARG ,
detachprofile_ARG ,
setactivationskip_ARG ,
- 1
} ;
return _is_option_listed ( opt_enum , options ) ;
}
/* Check @opt_enum requires direct commit/reload */
static int _option_requires_direct_commit ( int opt_enum )
{
int options [ ] = {
discards_ARG ,
zero_ARG ,
cachemode_ARG ,
cachepolicy_ARG ,
cachesettings_ARG ,
- 1
} ;
return _is_option_listed ( opt_enum , options ) ;
}
2016-11-17 01:05:47 +03:00
/*
* For each lvchange command definintion :
*
* lvchange_foo_cmd ( cmd , argc , argv ) ;
* . set cmd fields that apply to " foo "
* . set any other things that affect behavior of process_each
* . process_each_lv ( _lvchange_foo_single ) ;
*
* _lvchange_foo_single ( lv ) ;
* . _lvchange_foo ( lv ) ;
* . ( or all the code could live in the _single fn )
*/
2013-06-25 14:33:06 +04:00
2017-04-05 00:53:55 +03:00
/*
* Process 2 types of options differently
* minimizing metadata commits and table reloads :
*
* 1. process group of options not requiring metadata commit ( , reload )
* for each option and commit ( , reload ) metadata for the whole group
*
* 2. process the options requiring metadata commit + reload per option
*/
2016-11-17 01:05:47 +03:00
static int _lvchange_properties_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
2002-11-18 17:04:08 +03:00
{
2017-04-05 00:53:55 +03:00
int docmds = 0 , doit = 0 , doit_total = 0 , change_msg = 1 , second_group = 0 ;
2016-11-17 01:05:47 +03:00
int i , opt_enum ;
2017-04-05 00:53:55 +03:00
uint32_t mr = 0 ;
2016-04-25 14:44:42 +03:00
2018-05-24 19:41:14 +03:00
/*
* We do not acquire an lvmlockd lock on the LV here because these are
* VG metadata changes that do not conflict with the LV being active on
* another host .
*/
2002-11-18 17:04:08 +03:00
2017-04-05 00:53:55 +03:00
/* First group of options which allow for one metadata commit/update for the whole group */
2016-11-17 01:05:47 +03:00
for ( i = 0 ; i < cmd - > command - > ro_count ; i + + ) {
opt_enum = cmd - > command - > required_opt_args [ i ] . opt ;
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
if ( ! arg_is_set ( cmd , opt_enum ) )
continue ;
2017-04-05 00:53:55 +03:00
/*
2017-04-05 18:29:31 +03:00
* Skip options requiring direct commit / reload
2017-04-05 00:53:55 +03:00
* to process them in the second step .
*/
2017-04-05 18:29:31 +03:00
if ( _option_requires_direct_commit ( opt_enum ) ) {
2017-04-05 00:53:55 +03:00
second_group + + ;
continue ;
}
/* Archive will only happen once per run. */
2016-11-17 01:05:47 +03:00
if ( ! archive ( lv - > vg ) )
return_ECMD_FAILED ;
2017-04-05 00:53:55 +03:00
/*
* Process the following options and to a single
* metadata commit / reload for the whole group .
*/
2016-11-17 01:05:47 +03:00
switch ( opt_enum ) {
case permission_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_permission ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case alloc_ARG :
case contiguous_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_alloc ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case errorwhenfull_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_errorwhenfull ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case readahead_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_readahead ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case persistent_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_persistent ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case addtag_ARG :
case deltag_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_tag ( cmd , lv , opt_enum , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case writemostly_ARG :
case writebehind_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_writemostly ( lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case minrecoveryrate_ARG :
case maxrecoveryrate_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_recovery_rate ( lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case profile_ARG :
case metadataprofile_ARG :
case detachprofile_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_profile ( lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
case setactivationskip_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_activation_skip ( lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
2018-07-02 11:51:45 +03:00
case compression_ARG :
docmds + + ;
doit + = _lvchange_compression ( lv , & mr ) ;
break ;
case deduplication_ARG :
docmds + + ;
doit + = _lvchange_deduplication ( lv , & mr ) ;
break ;
2017-04-05 00:53:55 +03:00
default :
log_error ( INTERNAL_ERROR " Failed to check for option %s " ,
arg_long_option_name ( i ) ) ;
}
}
/* Any options of the first group processed? */
if ( docmds ) {
doit_total = doit ;
doit = 0 ;
/* Display any logical volume change */
if ( doit_total ) {
log_print_unless_silent ( " Logical volume %s changed. " , display_lvname ( lv ) ) ;
change_msg = 0 ;
/* Commit(, reload) metadata once for whole processed group of options */
if ( ! _commit_reload ( lv , mr ) )
return_ECMD_FAILED ;
}
/* Bail out if any processing of an option in the first group failed */
if ( docmds ! = doit_total )
return_ECMD_FAILED ;
/* Do backup if processing the first group of options went ok */
backup ( lv - > vg ) ;
} else if ( ! second_group )
return_ECMD_FAILED ;
/* Second group of options which need per option metadata commit+reload(s) */
for ( i = 0 ; i < cmd - > command - > ro_count ; i + + ) {
opt_enum = cmd - > command - > required_opt_args [ i ] . opt ;
if ( ! arg_is_set ( cmd , opt_enum ) )
continue ;
2017-04-05 18:29:31 +03:00
/* Skip any of the already processed options which allowed for group commit/reload */
if ( _option_allows_group_commit ( opt_enum ) )
2017-04-05 00:53:55 +03:00
continue ;
/* Archive will only happen once per run */
if ( ! archive ( lv - > vg ) )
return_ECMD_FAILED ;
mr = 0 ;
2017-04-05 18:29:31 +03:00
/* Run commit and reload after processing each of the following options */
2017-04-05 00:53:55 +03:00
switch ( opt_enum ) {
case discards_ARG :
case zero_ARG :
docmds + + ;
doit + = _lvchange_pool_update ( cmd , lv , & mr ) ;
break ;
2016-11-17 01:05:47 +03:00
case cachemode_ARG :
case cachepolicy_ARG :
case cachesettings_ARG :
2017-04-05 00:53:55 +03:00
docmds + + ;
2017-04-01 03:38:48 +03:00
doit + = _lvchange_cache ( cmd , lv , & mr ) ;
2016-11-17 01:05:47 +03:00
break ;
default :
2017-04-05 18:29:31 +03:00
log_error ( INTERNAL_ERROR " Failed to check for option %s " ,
arg_long_option_name ( i ) ) ;
2016-11-17 01:05:47 +03:00
}
2017-04-05 00:53:55 +03:00
/* Display any logical volume change unless already displayed in step 1. */
if ( doit & & change_msg ) {
log_print_unless_silent ( " Logical volume %s changed. " , display_lvname ( lv ) ) ;
change_msg = 0 ;
}
/* Commit(,reload) metadata per processed option */
if ( ! _commit_reload ( lv , mr ) )
return_ECMD_FAILED ;
2003-05-06 16:14:36 +04:00
}
2017-04-05 00:53:55 +03:00
doit_total + = doit ;
2016-11-17 01:05:47 +03:00
2017-04-05 00:53:55 +03:00
/* Bail out if no options wwre found or any processing of an option in the second group failed */
if ( ! docmds | | docmds ! = doit_total )
2016-11-17 01:05:47 +03:00
return_ECMD_FAILED ;
2017-04-05 00:53:55 +03:00
/* Do backup if processing the second group of options went ok */
backup ( lv - > vg ) ;
2017-04-01 03:38:48 +03:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
static int _lvchange_properties_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
2017-05-15 18:57:49 +03:00
/*
* Exceptions where we allow lvchange properties on
* a hidden sub lv .
*
* lv_is_thin_pool_data : e . g . needed when the data sublv
* is a cache lv and we need to change cache properties .
*/
if ( lv_is_thin_pool_data ( lv ) )
return 1 ;
2016-11-17 01:05:47 +03:00
if ( lv_is_named_arg )
2017-02-10 20:36:11 +03:00
log_error ( " Operation not permitted on hidden LV %s. " , display_lvname ( lv ) ) ;
2016-11-17 01:05:47 +03:00
return 0 ;
2005-06-01 20:51:55 +04:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
2009-05-27 22:19:21 +04:00
2016-11-17 01:05:47 +03:00
int lvchange_properties_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
int ret ;
2016-09-06 17:29:14 +03:00
2018-02-28 19:16:17 +03:00
if ( cmd - > activate_component ) {
log_error ( " Cannot change LV properties when activating component LVs. " ) ;
return 0 ;
}
2016-11-17 01:05:47 +03:00
/*
* A command def rule allows only some options when LV is partial ,
* so handles_missing_pvs will only affect those .
*/
2017-04-04 23:32:08 +03:00
init_background_polling ( arg_is_set ( cmd , sysinit_ARG ) ? 0 : arg_int_value ( cmd , poll_ARG , DEFAULT_BACKGROUND_POLLING ) ) ;
2016-11-17 01:05:47 +03:00
cmd - > handles_missing_pvs = 1 ;
ret = process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
NULL , & _lvchange_properties_check , & _lvchange_properties_single ) ;
if ( ret ! = ECMD_PROCESSED )
return ret ;
/*
* Unfortunately , lvchange has previously allowed changing an LV
* property and changing LV activation in a single command . This was
* not a good idea because the behavior / results are hard to predict and
* not possible to sensibly describe . It ' s also unnecessary . So , this
* is here for the sake of compatibility .
*
* This is extremely ugly ; activation should always be done separately .
* This is not the full - featured lvchange capability , just the basic
* ( the advanced activate options are not provided . )
*
* FIXME : wrap this in a config setting that we can disable by default
* to phase this out ?
*/
if ( arg_is_set ( cmd , activate_ARG ) ) {
log_warn ( " WARNING: Combining activation change with other commands is not advised. " ) ;
ret = lvchange_activate_cmd ( cmd , argc , argv ) ;
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
} else if ( arg_is_set ( cmd , monitor_ARG ) | | arg_is_set ( cmd , poll_ARG ) ) {
ret = lvchange_monitor_poll_cmd ( cmd , argc , argv ) ;
2005-06-03 18:49:51 +04:00
}
2016-11-17 01:05:47 +03:00
return ret ;
}
static int _lvchange_activate_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
struct logical_volume * origin ;
char snaps_msg [ 128 ] ;
/* FIXME: untangle the proper logic for cow / sparse / virtual origin */
/* If LV is sparse, activate origin instead */
if ( lv_is_cow ( lv ) & & lv_is_virtual_origin ( origin = origin_from_cow ( lv ) ) )
lv = origin ;
if ( lv_is_cow ( lv ) ) {
2014-08-15 17:51:03 +04:00
origin = origin_from_cow ( lv ) ;
2014-08-15 15:31:53 +04:00
if ( origin - > origin_count < 2 )
snaps_msg [ 0 ] = ' \0 ' ;
else if ( dm_snprintf ( snaps_msg , sizeof ( snaps_msg ) ,
" and %u other snapshot(s) " ,
origin - > origin_count - 1 ) < 0 ) {
log_error ( " Failed to prepare message. " ) ;
return ECMD_FAILED ;
}
2016-06-22 00:24:52 +03:00
if ( ! arg_is_set ( cmd , yes_ARG ) & &
2014-08-15 15:31:53 +04:00
( yes_no_prompt ( " Change of snapshot %s will also change its "
2014-08-15 17:52:01 +04:00
" origin %s%s. Proceed? [y/n]: " ,
display_lvname ( lv ) , display_lvname ( origin ) ,
snaps_msg ) = = ' n ' ) ) {
log_error ( " Logical volume %s not changed. " , display_lvname ( lv ) ) ;
2014-08-15 15:31:53 +04:00
return ECMD_FAILED ;
}
}
2016-11-17 01:05:47 +03:00
if ( ! _lvchange_activate ( cmd , lv ) )
return_ECMD_FAILED ;
2015-03-17 11:44:26 +03:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
static int _lvchange_activate_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
2018-02-28 19:16:17 +03:00
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 */
2016-11-17 01:05:47 +03:00
if ( lv_is_named_arg )
2017-02-10 20:36:11 +03:00
log_error ( " Operation not permitted on hidden LV %s. " , display_lvname ( lv ) ) ;
2016-11-17 01:05:47 +03:00
return 0 ;
2015-03-05 23:00:44 +03:00
}
2018-07-02 11:51:45 +03:00
if ( lv_is_vdo_pool ( lv ) & & ! lv_is_named_arg )
return 0 ; /* Skip VDO pool processing unless explicitely named */
2016-11-17 01:05:47 +03:00
return 1 ;
}
int lvchange_activate_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
int ret ;
2018-02-26 16:44:51 +03:00
int do_activate = is_change_activating ( ( activation_change_t ) arg_uint_value ( cmd , activate_ARG , CHANGE_AY ) ) ;
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
2017-04-04 23:32:08 +03:00
init_background_polling ( arg_is_set ( cmd , sysinit_ARG ) ? 0 : arg_int_value ( cmd , poll_ARG , DEFAULT_BACKGROUND_POLLING ) ) ;
2016-11-17 01:05:47 +03:00
cmd - > handles_missing_pvs = 1 ;
cmd - > lockd_vg_default_sh = 1 ;
2010-01-06 22:08:58 +03:00
/*
2016-11-17 01:05:47 +03:00
* Include foreign VGs that contain active LVs .
* That shouldn ' t happen in general , but if it does by some
* mistake , then we want to allow those LVs to be deactivated .
2010-01-06 22:08:58 +03:00
*/
2016-11-17 01:05:47 +03:00
cmd - > include_active_foreign_vgs = 1 ;
2010-01-05 23:56:51 +03:00
2016-11-17 01:05:47 +03:00
/* Allow deactivating if locks fail. */
2018-02-26 16:44:51 +03:00
if ( do_activate )
2016-11-17 01:05:47 +03:00
cmd - > lockd_vg_enforce_sh = 1 ;
2002-11-18 17:04:08 +03:00
2018-02-28 19:16:17 +03:00
/* 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 ;
2018-06-06 19:14:39 +03:00
ret = process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
NULL , & _lvchange_activate_check , & _lvchange_activate_single ) ;
if ( ret ! = ECMD_PROCESSED )
return ret ;
if ( arg_is_set ( cmd , monitor_ARG ) | | arg_is_set ( cmd , poll_ARG ) )
ret = lvchange_monitor_poll_cmd ( cmd , argc , argv ) ;
return ret ;
2016-11-17 01:05:47 +03:00
}
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
static int _lvchange_refresh_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
log_verbose ( " Refreshing logical volume %s (if active). " , display_lvname ( lv ) ) ;
2015-01-15 17:20:08 +03:00
2016-11-17 01:05:47 +03:00
if ( ! lv_refresh ( cmd , lv ) )
return_ECMD_FAILED ;
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
/*
* FIXME : In some cases , the lv_refresh ( ) starts polling without
* checking poll arg . Pull that out of lv_refresh .
*/
if ( arg_is_set ( cmd , poll_ARG ) & &
! _lvchange_background_polling ( cmd , lv ) )
return_ECMD_FAILED ;
2002-11-18 17:04:08 +03:00
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
if ( arg_is_set ( cmd , monitor_ARG ) & &
! _lvchange_monitoring ( cmd , lv ) )
return_ECMD_FAILED ;
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
2012-06-28 16:52:23 +04:00
2016-11-17 01:05:47 +03:00
static int _lvchange_refresh_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
2017-02-10 20:36:11 +03:00
log_error ( " Operation not permitted on hidden LV %s. " , display_lvname ( lv ) ) ;
2016-11-17 01:05:47 +03:00
return 0 ;
2004-03-08 20:19:15 +03:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
2004-03-08 20:19:15 +03:00
2016-11-17 01:05:47 +03:00
int lvchange_refresh_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
2017-04-04 23:32:08 +03:00
init_background_polling ( arg_is_set ( cmd , sysinit_ARG ) ? 0 : arg_int_value ( cmd , poll_ARG , DEFAULT_BACKGROUND_POLLING ) ) ;
2016-11-17 01:05:47 +03:00
cmd - > handles_missing_pvs = 1 ;
cmd - > lockd_vg_default_sh = 1 ;
2016-08-05 16:54:49 +03:00
2016-11-17 01:05:47 +03:00
return process_each_lv ( cmd , argc , argv , NULL , NULL , 0 ,
NULL , & _lvchange_refresh_check , & _lvchange_refresh_single ) ;
}
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
2016-11-17 01:05:47 +03:00
static int _lvchange_resync_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
2017-04-05 23:05:32 +03:00
/* If LV is inactive here, ensure it's not active elsewhere. */
if ( ! lockd_lv ( cmd , lv , " ex " , 0 ) )
return_ECMD_FAILED ;
2016-11-17 01:05:47 +03:00
if ( ! _lvchange_resync ( cmd , lv ) )
return_ECMD_FAILED ;
2013-05-31 20:25:52 +04:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
2013-06-25 14:33:06 +04:00
2016-11-17 01:05:47 +03:00
static int _lvchange_resync_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
return 1 ;
return 0 ;
2013-07-11 14:44:36 +04:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
int lvchange_resync_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
int ret ;
ret = process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
NULL , & _lvchange_resync_check , & _lvchange_resync_single ) ;
if ( ret ! = ECMD_PROCESSED )
return ret ;
/*
* Unfortunately , lvchange has previously allowed resync and changing
* activation to be combined in one command . activate should be
* done separately , but this is here to avoid breaking commands that
* used this .
*
* FIXME : wrap this in a config setting that we can disable by default
* to phase this out ?
*/
if ( arg_is_set ( cmd , activate_ARG ) ) {
log_warn ( " WARNING: Combining activation change with other commands is not advised. " ) ;
ret = lvchange_activate_cmd ( cmd , argc , argv ) ;
2014-11-19 20:39:58 +03:00
}
2016-11-17 01:05:47 +03:00
return ret ;
}
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
static int _lvchange_syncaction_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
2017-04-05 23:05:32 +03:00
/* If LV is inactive here, ensure it's not active elsewhere. */
if ( ! lockd_lv ( cmd , lv , " ex " , 0 ) )
return_ECMD_FAILED ;
2016-11-17 01:05:47 +03:00
if ( ! lv_raid_message ( lv , arg_str_value ( cmd , syncaction_ARG , NULL ) ) )
2013-07-01 13:27:22 +04:00
return_ECMD_FAILED ;
2006-10-24 03:03:55 +04:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
2016-07-12 18:20:38 +03:00
2016-11-17 01:05:47 +03:00
static int _lvchange_syncaction_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
return 1 ;
return 0 ;
2016-07-12 18:20:38 +03:00
}
2013-04-12 00:33:59 +04:00
2016-11-17 01:05:47 +03:00
return 1 ;
}
2006-05-12 23:16:48 +04:00
2016-11-17 01:05:47 +03:00
int lvchange_syncaction_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
return process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
NULL , & _lvchange_syncaction_check , & _lvchange_syncaction_single ) ;
}
2010-01-05 23:56:51 +03:00
2016-11-17 01:05:47 +03:00
static int _lvchange_rebuild_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
2017-04-05 23:05:32 +03:00
/* If LV is inactive here, ensure it's not active elsewhere. */
if ( ! lockd_lv ( cmd , lv , " ex " , 0 ) )
return_ECMD_FAILED ;
2016-11-17 01:05:47 +03:00
if ( ! _lvchange_rebuild ( lv ) )
2013-07-01 13:27:22 +04:00
return_ECMD_FAILED ;
2008-07-31 17:03:01 +04:00
2003-10-22 02:06:07 +04:00
return ECMD_PROCESSED ;
2002-11-18 17:04:08 +03:00
}
2016-11-17 01:05:47 +03:00
static int _lvchange_rebuild_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
2002-11-18 17:04:08 +03:00
{
2016-11-17 01:05:47 +03:00
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
return 1 ;
return 0 ;
2002-11-18 17:04:08 +03:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
2013-06-25 14:33:06 +04:00
2016-11-17 01:05:47 +03:00
int lvchange_rebuild_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
return process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
NULL , & _lvchange_rebuild_check , & _lvchange_rebuild_single ) ;
}
2009-07-15 09:47:55 +04:00
2016-11-17 01:05:47 +03:00
static int _lvchange_monitor_poll_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
if ( arg_is_set ( cmd , monitor_ARG ) & &
! _lvchange_monitoring ( cmd , lv ) )
return_ECMD_FAILED ;
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
if ( arg_is_set ( cmd , poll_ARG ) & &
! _lvchange_background_polling ( cmd , lv ) )
return_ECMD_FAILED ;
2009-07-15 09:47:55 +04:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
static int _lvchange_monitor_poll_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
return 1 ;
return 0 ;
2003-04-02 23:14:43 +04:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
2002-11-18 17:04:08 +03:00
2016-11-17 01:05:47 +03:00
int lvchange_monitor_poll_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
2017-04-04 23:32:08 +03:00
init_background_polling ( arg_is_set ( cmd , sysinit_ARG ) ? 0 : arg_int_value ( cmd , poll_ARG , DEFAULT_BACKGROUND_POLLING ) ) ;
2016-11-17 01:05:47 +03:00
cmd - > handles_missing_pvs = 1 ;
return process_each_lv ( cmd , argc , argv , NULL , NULL , 0 ,
NULL , & _lvchange_monitor_poll_check , & _lvchange_monitor_poll_single ) ;
}
2004-05-19 02:12:53 +04:00
2016-11-17 01:05:47 +03:00
static int _lvchange_persistent_single ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle )
{
2017-04-05 00:53:55 +03:00
uint32_t mr = 0 ;
2017-04-01 03:38:48 +03:00
2017-04-05 23:05:32 +03:00
/* If LV is inactive here, ensure it's not active elsewhere. */
if ( ! lockd_lv ( cmd , lv , " ex " , 0 ) )
return_ECMD_FAILED ;
2017-04-01 03:38:48 +03:00
if ( ! _lvchange_persistent ( cmd , lv , & mr ) )
return_ECMD_FAILED ;
2017-04-05 00:53:55 +03:00
if ( ! _commit_reload ( lv , mr ) )
2016-11-17 01:05:47 +03:00
return_ECMD_FAILED ;
2010-05-06 15:15:55 +04:00
2016-11-17 01:05:47 +03:00
return ECMD_PROCESSED ;
}
static int _lvchange_persistent_check ( struct cmd_context * cmd ,
struct logical_volume * lv ,
struct processing_handle * handle ,
int lv_is_named_arg )
{
if ( ! lv_is_visible ( lv ) ) {
if ( lv_is_named_arg )
2017-02-10 20:36:11 +03:00
log_error ( " Operation not permitted on hidden LV %s. " , display_lvname ( lv ) ) ;
2016-11-17 01:05:47 +03:00
return 0 ;
2012-07-10 15:49:46 +04:00
}
2016-11-17 01:05:47 +03:00
return 1 ;
}
2015-02-25 20:33:11 +03:00
2016-11-17 01:05:47 +03:00
int lvchange_persistent_cmd ( struct cmd_context * cmd , int argc , char * * argv )
{
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
int ret ;
2017-04-04 23:32:08 +03:00
init_background_polling ( arg_is_set ( cmd , sysinit_ARG ) ? 0 : arg_int_value ( cmd , poll_ARG , DEFAULT_BACKGROUND_POLLING ) ) ;
2016-11-17 01:05:47 +03:00
cmd - > handles_missing_pvs = 1 ;
vgchange/lvchange: fix poll and monitor use
Fill in some gaps where old versions of lvm allowed
--poll and --monitor in combination with other operations,
but those combinations had been lost since the cmd def work.
(The new cmd def code also added some combinations that
had been missed by the old code.)
Changes:
lvchange --activate: add poll and monitor options, and
add calls to them in implementation.
lvchange --refresh: add monitor option (poll already there),
and call to monitor in implementation.
lvchange <metadata ops>: add poll and monitor options, and
add calls to them in implementation.
vgchange <metadata ops>: add poll option (call to poll
already in implementation).
vgchange --refresh: remove monitor option (not used by code)
lvchange --persistent y: add poll and monitor options, and
add calls to them, and to activate
in the implementation. (Making it
match the main lvchange metadata
command.)
Summary of current usage:
lvchange --activate: monitor, poll
vgchange --activate: monitor, poll
lvchange --refresh: monitor, poll
vgchange --refresh: poll
lvchange --monitor: ok
lvchange --poll: ok
lvchange --monitor --poll: ok
vgchange --monitor: ok
vgchange --poll: ok
vgchange --monitor --poll: ok
lvchange <metadata ops>: monitor, poll
vgchange <metadata ops>: poll
2017-04-04 20:52:29 +03:00
ret = process_each_lv ( cmd , argc , argv , NULL , NULL , READ_FOR_UPDATE ,
NULL , & _lvchange_persistent_check , & _lvchange_persistent_single ) ;
if ( ret ! = ECMD_PROCESSED )
return ret ;
/* See comment in lvchange_properties about needing to allow these. */
if ( arg_is_set ( cmd , activate_ARG ) ) {
log_warn ( " WARNING: Combining activation change with other commands is not advised. " ) ;
ret = lvchange_activate_cmd ( cmd , argc , argv ) ;
} else if ( arg_is_set ( cmd , monitor_ARG ) | | arg_is_set ( cmd , poll_ARG ) ) {
ret = lvchange_monitor_poll_cmd ( cmd , argc , argv ) ;
}
2017-04-05 18:08:01 +03:00
return ret ;
2016-11-17 01:05:47 +03:00
}
2015-03-05 23:00:44 +03:00
2016-11-17 01:05:47 +03:00
int lvchange ( struct cmd_context * cmd , int argc , char * * argv )
{
2017-02-10 20:36:11 +03:00
log_error ( INTERNAL_ERROR " Missing function for command definition %d:%s. " ,
cmd - > command - > command_index , cmd - > command - > command_id ) ;
2016-11-17 01:05:47 +03:00
return ECMD_FAILED ;
2002-11-18 17:04:08 +03:00
}