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 .
2011-11-18 23:22:49 +04:00
* Copyright ( C ) 2004 - 2011 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 ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2001-10-30 17:32:48 +03:00
*/
# include "tools.h"
2002-02-12 00:00:35 +03:00
static int lvchange_permission ( struct cmd_context * cmd ,
struct logical_volume * lv )
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 ;
2009-04-21 18:31:57 +04:00
int r = 0 ;
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 ) ) {
2002-02-12 00:00:35 +03:00
log_error ( " Logical volume \" %s \" is already writable " ,
lv - > name ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
if ( ! ( lv_access & LVM_WRITE ) & & ! ( lv - > status & LVM_WRITE ) ) {
2002-02-12 00:00:35 +03:00
log_error ( " Logical volume \" %s \" is already read only " ,
lv - > name ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
2008-04-10 21:09:32 +04:00
if ( ( lv - > status & MIRRORED ) & & ( vg_is_clustered ( lv - > vg ) ) & &
2010-08-17 20:25:32 +04:00
lv_info ( cmd , lv , 0 , & info , 0 , 0 ) & & info . exists ) {
2007-01-10 22:56:39 +03:00
log_error ( " Cannot change permissions of mirror \" %s \" "
" while active. " , lv - > name ) ;
return 0 ;
}
2011-12-01 04:04:21 +04:00
/* Not allowed to change permissions on RAID sub-LVs directly */
if ( ( lv - > status & RAID_META ) | | ( lv - > status & RAID_IMAGE ) ) {
log_error ( " Cannot change permissions of RAID %s \" %s \" " ,
( lv - > status & RAID_IMAGE ) ? " image " :
" metadata area " , lv - > name ) ;
return 0 ;
}
2001-10-30 17:32:48 +03:00
if ( lv_access & LVM_WRITE ) {
lv - > status | = LVM_WRITE ;
2002-02-12 00:00:35 +03:00
log_verbose ( " Setting logical volume \" %s \" read/write " ,
lv - > name ) ;
2001-10-30 17:32:48 +03:00
} else {
lv - > status & = ~ LVM_WRITE ;
2002-02-12 00:00:35 +03:00
log_verbose ( " Setting logical volume \" %s \" read-only " ,
lv - > name ) ;
2001-10-30 17:32:48 +03:00
}
2003-07-05 02:34:56 +04:00
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! vg_write ( lv - > vg ) )
return_0 ;
2003-07-05 02:34:56 +04:00
2005-08-15 16:00:04 +04:00
if ( ! suspend_lv ( cmd , lv ) ) {
2002-02-21 00:30:27 +03:00
log_error ( " Failed to lock %s " , lv - > name ) ;
2003-07-05 02:34:56 +04:00
vg_revert ( lv - > vg ) ;
2009-04-21 18:31:57 +04:00
goto out ;
2002-02-21 00:30:27 +03:00
}
2003-07-05 02:34:56 +04:00
if ( ! vg_commit ( lv - > vg ) ) {
2010-01-06 00:07:31 +03:00
if ( ! resume_lv ( cmd , lv ) )
stack ;
2009-04-21 18:31:57 +04:00
goto_out ;
2002-02-21 00:30:27 +03:00
}
2001-10-31 20:59:52 +03:00
2002-01-30 18:04:48 +03:00
log_very_verbose ( " Updating permissions for \" %s \" in kernel " , lv - > name ) ;
2005-08-15 16:00:04 +04:00
if ( ! resume_lv ( cmd , lv ) ) {
2002-04-24 22:20:51 +04:00
log_error ( " Problem reactivating %s " , lv - > name ) ;
2009-04-21 18:31:57 +04:00
goto out ;
2002-04-24 22:20:51 +04:00
}
2001-10-31 20:59:52 +03:00
2009-04-22 16:46:25 +04:00
r = 1 ;
2009-04-21 18:31:57 +04:00
out :
backup ( lv - > vg ) ;
return r ;
2001-10-30 17:32:48 +03:00
}
2012-06-28 16:52:23 +04:00
static int lvchange_pool_update ( struct cmd_context * cmd ,
struct logical_volume * lv )
{
int r = 0 ;
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
if ( ! lv_is_thin_pool ( lv ) ) {
2012-08-07 23:08:14 +04:00
log_error ( " Logical volume \" %s \" is not a thin pool. " , lv - > name ) ;
2012-06-28 16:52:23 +04:00
return 0 ;
}
2012-08-08 00:24:41 +04:00
if ( arg_count ( 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 ) {
if ( ( ( discards = = THIN_DISCARDS_IGNORE ) | |
( first_seg ( lv ) - > discards = = THIN_DISCARDS_IGNORE ) ) & &
2012-06-28 16:52:23 +04:00
lv_is_active ( lv ) )
2012-08-08 00:24:41 +04:00
log_error ( " Cannot change discards state for active "
2012-06-28 16:52:23 +04:00
" logical volume \" %s \" . " , lv - > name ) ;
else {
2012-08-08 00:24:41 +04:00
first_seg ( lv ) - > discards = discards ;
2012-06-28 16:52:23 +04:00
update + + ;
}
} else
2012-08-08 00:24:41 +04:00
log_error ( " Logical volume \" %s \" already uses --discards %s. " ,
lv - > name , get_pool_discards_name ( discards ) ) ;
2012-06-28 16:52:23 +04:00
}
if ( arg_count ( cmd , zero_ARG ) ) {
val = arg_uint_value ( cmd , zero_ARG , 1 ) ;
if ( val ! = first_seg ( lv ) - > zero_new_blocks ) {
first_seg ( lv ) - > zero_new_blocks = val ;
update + + ;
} else
log_error ( " Logical volume \" %s \" already %szero new blocks. " ,
lv - > name , val ? " " : " does not " ) ;
}
if ( ! update )
return 0 ;
log_very_verbose ( " Updating logical volume \" %s \" on disk(s). " , lv - > name ) ;
if ( ! vg_write ( lv - > vg ) )
return_0 ;
if ( ! suspend_lv_origin ( cmd , lv ) ) {
log_error ( " Failed to update active %s/%s (deactivation is needed). " ,
lv - > vg - > name , lv - > name ) ;
vg_revert ( lv - > vg ) ;
goto out ;
}
if ( ! vg_commit ( lv - > vg ) ) {
if ( ! resume_lv_origin ( cmd , lv ) )
stack ;
goto_out ;
}
if ( ! resume_lv_origin ( cmd , lv ) ) {
log_error ( " Problem reactivating %s. " , lv - > name ) ;
goto out ;
}
r = 1 ;
out :
backup ( lv - > vg ) ;
return r ;
}
2007-01-20 01:21:45 +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 ) {
2006-05-12 23:16:48 +04:00
log_error ( " Logical volume, %s, is not active " , lv - > name ) ;
return 0 ;
}
2007-01-20 01:21:45 +03:00
/* do not monitor pvmove lv's */
2006-05-12 23:16:48 +04:00
if ( lv - > status & PVMOVE )
return 1 ;
2007-01-25 02:43:27 +03:00
if ( ( dmeventd_monitor_mode ( ) ! = DMEVENTD_MONITOR_IGNORE ) & &
2010-08-17 20:25:32 +04:00
! monitor_dev_for_events ( cmd , lv , 0 , dmeventd_monitor_mode ( ) ) )
2010-08-17 02:54:35 +04:00
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
}
2010-01-05 23:56:51 +03:00
static int lvchange_background_polling ( struct cmd_context * cmd ,
struct logical_volume * lv )
{
struct lvinfo info ;
2010-08-17 20:25:32 +04:00
if ( ! lv_info ( cmd , lv , 0 , & info , 0 , 0 ) | | ! info . exists ) {
2010-01-05 23:56:51 +03:00
log_error ( " Logical volume, %s, is not active " , lv - > name ) ;
return 0 ;
}
if ( background_polling ( ) )
lv_spawn_background_polling ( cmd , lv ) ;
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
{
2004-05-24 17:44:10 +04:00
int activate ;
2001-10-30 17:32:48 +03:00
2012-06-27 15:48:31 +04:00
activate = arg_uint_value ( cmd , activate_ARG , 0 ) ;
2001-10-30 17:32:48 +03:00
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 ) ;
2012-06-27 18:43:20 +04:00
if ( activate = = CHANGE_AAY ) {
if ( ! lv_passes_auto_activation_filter ( cmd , lv ) )
return 1 ;
activate = CHANGE_ALY ;
}
2004-06-16 21:13:41 +04:00
if ( activate = = CHANGE_ALN ) {
log_verbose ( " Deactivating logical volume \" %s \" locally " ,
lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! deactivate_lv_local ( cmd , lv ) )
return_0 ;
2004-06-16 21:13:41 +04:00
} else if ( activate = = CHANGE_AN ) {
log_verbose ( " Deactivating logical volume \" %s \" " , lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! deactivate_lv ( cmd , lv ) )
return_0 ;
2004-06-16 21:13:41 +04:00
} else {
2011-10-29 00:29:06 +04:00
if ( ( activate = = CHANGE_AE ) | |
lv_is_origin ( lv ) | |
lv_is_thin_type ( lv ) ) {
2004-06-16 21:13:41 +04:00
log_verbose ( " Activating logical volume \" %s \" "
" exclusively " , lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! activate_lv_excl ( cmd , lv ) )
return_0 ;
2004-06-16 21:13:41 +04:00
} else if ( activate = = CHANGE_ALY ) {
log_verbose ( " Activating logical volume \" %s \" locally " ,
lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! activate_lv_local ( cmd , lv ) )
return_0 ;
2004-06-16 21:13:41 +04:00
} else {
log_verbose ( " Activating logical volume \" %s \" " ,
lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! activate_lv ( cmd , lv ) )
return_0 ;
2004-05-05 21:56:20 +04:00
}
2004-06-16 21:13:41 +04:00
2010-01-05 23:56:51 +03:00
if ( background_polling ( ) )
lv_spawn_background_polling ( cmd , lv ) ;
2002-01-08 01:36:12 +03:00
}
2001-10-30 17:32:48 +03:00
return 1 ;
}
2004-03-27 00:24:03 +03:00
static int lvchange_refresh ( struct cmd_context * cmd , struct logical_volume * lv )
{
log_verbose ( " Refreshing logical volume \" %s \" (if active) " , lv - > name ) ;
2010-08-17 23:25:05 +04:00
2008-12-19 17:22:48 +03:00
return lv_refresh ( cmd , lv ) ;
2004-03-27 00:24:03 +03:00
}
2012-09-11 22:01:05 +04:00
static int detach_metadata_devices ( struct lv_segment * seg , struct dm_list * list )
{
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 cmd_context * cmd = seg - > lv - > vg - > cmd ;
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
2012-09-11 22:09:35 +04:00
if ( ! ( lvl = dm_pool_alloc ( cmd - > mem , sizeof ( * lvl ) * num_meta_lvs ) ) )
2012-09-11 22:01:05 +04:00
return_0 ;
2012-09-11 22:09:35 +04:00
if ( seg_is_raid ( seg ) ) {
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 ;
}
static int attach_metadata_devices ( struct lv_segment * seg , struct dm_list * list )
{
struct cmd_context * cmd = seg - > lv - > vg - > cmd ;
2012-09-11 22:09:35 +04:00
struct lv_list * lvl , * tmp ;
2012-09-11 22:01:05 +04:00
if ( seg_is_raid ( seg ) ) {
2012-09-11 22:09:35 +04:00
dm_list_iterate_items_safe ( lvl , tmp , list ) {
lv_set_hidden ( lvl - > lv ) ;
dm_pool_free ( cmd - > mem , lvl ) ;
}
return 1 ;
2012-09-11 22:01:05 +04:00
}
dm_list_iterate_items ( lvl , list )
break ; /* get first item */
if ( ! attach_mirror_log ( seg , lvl - > lv ) ) {
dm_pool_free ( cmd - > mem , lvl ) ;
return_0 ;
}
dm_pool_free ( cmd - > mem , lvl ) ;
return 1 ;
}
2006-10-24 21:18:25 +04:00
static int lvchange_resync ( struct cmd_context * cmd ,
2006-10-24 03:03:55 +04:00
struct logical_volume * lv )
{
int active = 0 ;
2008-05-21 18:10:11 +04:00
int monitored ;
2006-10-24 03:03:55 +04:00
struct lvinfo info ;
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
2012-09-11 22:09:35 +04:00
if ( ! ( lv - > status & MIRRORED ) & & ! seg_is_raid ( seg ) ) {
log_error ( " Unable to resync %s. It is not RAID or mirrored. " ,
2006-10-24 03:03:55 +04:00
lv - > name ) ;
return 1 ;
}
if ( lv - > status & PVMOVE ) {
log_error ( " Unable to resync pvmove volume %s " , lv - > name ) ;
return 0 ;
}
if ( lv - > status & LOCKED ) {
log_error ( " Unable to resync locked volume %s " , lv - > name ) ;
return 0 ;
}
2010-08-17 20:25:32 +04:00
if ( lv_info ( cmd , lv , 0 , & info , 1 , 0 ) ) {
2006-10-24 03:03:55 +04:00
if ( info . open_count ) {
log_error ( " Can't resync open logical volume \" %s \" " ,
lv - > name ) ;
2009-05-20 13:55:33 +04:00
return 0 ;
2006-10-24 03:03:55 +04:00
}
2006-10-24 19:30:33 +04:00
if ( info . exists ) {
if ( ! arg_count ( cmd , yes_ARG ) & &
yes_no_prompt ( " Do you really want to deactivate "
2006-10-24 03:03:55 +04:00
" logical volume %s to resync it? [y/n]: " ,
lv - > name ) = = ' n ' ) {
2009-12-03 22:18:33 +03:00
log_error ( " Logical volume \" %s \" not resynced " ,
2006-10-24 03:03:55 +04:00
lv - > name ) ;
2009-05-20 13:55:33 +04:00
return 0 ;
2006-10-24 03:03:55 +04:00
}
2007-06-15 14:11:14 +04:00
if ( sigint_caught ( ) )
2009-05-20 13:55:33 +04:00
return 0 ;
2007-06-15 14:11:14 +04:00
2006-10-24 19:30:33 +04:00
active = 1 ;
}
2006-10-24 03:03:55 +04:00
}
2008-05-21 18:10:11 +04:00
/* Activate exclusively to ensure no nodes still have LV active */
monitored = dmeventd_monitor_mode ( ) ;
init_dmeventd_monitor ( 0 ) ;
2006-10-24 03:03:55 +04:00
if ( ! deactivate_lv ( cmd , lv ) ) {
log_error ( " Unable to deactivate %s for resync " , lv - > name ) ;
return 0 ;
}
2009-05-20 13:55:33 +04:00
if ( vg_is_clustered ( lv - > vg ) & & lv_is_active ( lv ) ) {
log_error ( " Can't get exclusive access to clustered volume %s " ,
lv - > name ) ;
return 0 ;
}
2008-05-21 18:10:11 +04:00
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
2012-09-11 22:09:35 +04: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 " ,
seg - > segtype - > ops - > name ( seg ) , lv - > name ) ;
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 ) {
2012-09-19 20:09:32 +04:00
if ( lv - > status & LV_NOTSYNCED ) {
2012-09-11 21:55:17 +04:00
lv - > status & = ~ LV_NOTSYNCED ;
log_very_verbose ( " Updating logical volume \" %s \" "
" on disk(s) " , lv - > name ) ;
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) ) {
log_error ( " Failed to update metadata on disk. " ) ;
return 0 ;
}
}
2006-10-24 03:03:55 +04:00
if ( active & & ! activate_lv ( cmd , lv ) ) {
log_error ( " Failed to reactivate %s to resynchronize "
" mirror " , lv - > name ) ;
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 */
if ( ! detach_metadata_devices ( seg , & device_list ) ) {
log_error ( " Failed to clear %s %s for %s " ,
seg - > segtype - > name , seg_is_raid ( seg ) ?
" metadata area " : " mirror log " , lv - > name ) ;
return 0 ;
}
2006-10-24 03:03:55 +04:00
2012-09-11 21:55:17 +04:00
if ( ! vg_write ( lv - > vg ) ) {
log_error ( " Failed to write intermediate VG metadata. " ) ;
2012-09-11 22:01:05 +04:00
if ( ! attach_metadata_devices ( seg , & device_list ) )
2012-09-11 21:55:17 +04:00
stack ;
if ( active & & ! activate_lv ( cmd , lv ) )
stack ;
return 0 ;
}
2006-10-24 03:03:55 +04:00
2012-09-11 21:55:17 +04:00
if ( ! vg_commit ( lv - > vg ) ) {
log_error ( " Failed to commit intermediate VG metadata. " ) ;
2012-09-11 22:01:05 +04:00
if ( ! attach_metadata_devices ( seg , & device_list ) )
2012-09-11 21:55:17 +04:00
stack ;
if ( active & & ! activate_lv ( cmd , lv ) )
stack ;
return 0 ;
}
2009-04-21 18:31:57 +04:00
2012-09-11 21:55:17 +04:00
backup ( lv - > vg ) ;
2006-10-24 03:03:55 +04:00
2012-09-11 22:01:05 +04:00
dm_list_iterate_items ( lvl , & device_list ) {
if ( ! activate_lv ( cmd , lvl - > lv ) ) {
log_error ( " Unable to activate %s for mirror log resync " ,
lvl - > lv - > name ) ;
return 0 ;
}
2006-10-24 03:03:55 +04:00
2012-09-11 22:01:05 +04:00
log_very_verbose ( " Clearing %s device %s " ,
( seg_is_raid ( seg ) ) ? " metadata " : " log " ,
lvl - > lv - > name ) ;
if ( ! set_lv ( cmd , lvl - > lv , lvl - > lv - > size , 0 ) ) {
log_error ( " Unable to reset sync status for %s " ,
lv - > name ) ;
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 "
" after wiping for resync " ,
( seg_is_raid ( seg ) ) ? " metadata " : " log " ,
lvl - > lv - > name ) ;
return 0 ;
}
2012-09-11 21:55:17 +04:00
}
2006-10-24 03:03:55 +04:00
2012-09-11 22:01:05 +04:00
/* Put metadata sub-LVs back in place */
if ( ! attach_metadata_devices ( seg , & device_list ) ) {
log_error ( " Failed to reattach %s device after clearing " ,
( seg_is_raid ( seg ) ) ? " metadata " : " log " ) ;
2012-09-11 21:55:17 +04:00
return 0 ;
2006-10-24 03:03:55 +04:00
}
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) ) {
log_error ( " Failed to update metadata on disk. " ) ;
return 0 ;
}
if ( active & & ! activate_lv ( cmd , lv ) ) {
log_error ( " Failed to reactivate %s after resync " , lv - > name ) ;
return 0 ;
}
return 1 ;
}
2004-05-19 02:12:53 +04:00
static int lvchange_alloc ( struct cmd_context * cmd , struct logical_volume * lv )
2001-10-30 17:32:48 +03:00
{
2002-07-11 18:21:49 +04:00
int want_contiguous = 0 ;
2004-05-19 02:12:53 +04:00
alloc_policy_t alloc ;
2001-10-30 17:32:48 +03:00
2004-05-19 02:12:53 +04:00
want_contiguous = strcmp ( arg_str_value ( cmd , contiguous_ARG , " n " ) , " n " ) ;
alloc = want_contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT ;
2012-02-28 18:24:57 +04:00
alloc = ( alloc_policy_t ) arg_uint_value ( cmd , alloc_ARG , alloc ) ;
2001-10-30 17:32:48 +03:00
2004-05-19 02:12:53 +04:00
if ( alloc = = lv - > alloc ) {
2002-01-30 18:04:48 +03:00
log_error ( " Allocation policy of logical volume \" %s \" is "
2004-05-19 02:12:53 +04:00
" already %s " , lv - > name , 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
2004-05-19 02:12:53 +04:00
log_verbose ( " Setting contiguous allocation policy for \" %s \" to %s " ,
lv - > name , get_alloc_string ( alloc ) ) ;
2001-10-30 17:32:48 +03:00
2003-07-05 02:34:56 +04:00
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
2004-05-19 02:12:53 +04:00
2009-04-21 18:31:57 +04:00
/* No need to suspend LV for this change */
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2003-07-05 02:34:56 +04:00
backup ( lv - > vg ) ;
2001-10-30 17:32:48 +03:00
return 1 ;
}
2002-02-12 00:00:35 +03:00
static int lvchange_readahead ( struct cmd_context * cmd ,
struct logical_volume * lv )
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 ;
2009-04-21 18:31:57 +04:00
int r = 0 ;
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 )
log_error ( " Read ahead is already auto for \" %s \" " , lv - > name ) ;
else
log_error ( " Read ahead is already %u for \" %s \" " ,
read_ahead , lv - > name ) ;
2001-10-30 17:32:48 +03:00
return 0 ;
}
lv - > read_ahead = read_ahead ;
2002-02-21 00:30:27 +03:00
2002-02-12 00:00:35 +03:00
log_verbose ( " Setting read ahead to %u for \" %s \" " , read_ahead ,
lv - > name ) ;
2001-10-30 17:32:48 +03:00
2003-07-05 02:34:56 +04:00
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
2008-01-30 16:19:47 +03:00
if ( ! vg_write ( lv - > vg ) )
return_0 ;
2003-07-05 02:34:56 +04:00
2005-08-15 16:00:04 +04:00
if ( ! suspend_lv ( cmd , lv ) ) {
2002-02-21 00:30:27 +03:00
log_error ( " Failed to lock %s " , lv - > name ) ;
2003-07-05 02:34:56 +04:00
vg_revert ( lv - > vg ) ;
2009-04-21 18:31:57 +04:00
goto out ;
2002-02-21 00:30:27 +03:00
}
2001-10-31 20:59:52 +03:00
2003-07-05 02:34:56 +04:00
if ( ! vg_commit ( lv - > vg ) ) {
2010-01-06 00:07:31 +03:00
if ( ! resume_lv ( cmd , lv ) )
stack ;
2009-04-21 18:31:57 +04:00
goto_out ;
2002-02-21 00:30:27 +03:00
}
2001-10-31 20:59:52 +03:00
2003-07-05 02:34:56 +04:00
log_very_verbose ( " Updating permissions for \" %s \" in kernel " , lv - > name ) ;
2005-08-15 16:00:04 +04:00
if ( ! resume_lv ( cmd , lv ) ) {
2002-04-24 22:20:51 +04:00
log_error ( " Problem reactivating %s " , lv - > name ) ;
2009-04-21 18:31:57 +04:00
goto out ;
2002-04-24 22:20:51 +04:00
}
2002-02-21 00:30:27 +03:00
2009-04-21 18:31:57 +04:00
r = 1 ;
out :
backup ( lv - > vg ) ;
return r ;
2001-10-30 17:32:48 +03:00
}
2002-02-01 20:54:39 +03:00
2002-02-12 00:00:35 +03:00
static int lvchange_persistent ( struct cmd_context * cmd ,
struct logical_volume * lv )
2002-02-01 20:54:39 +03:00
{
2003-07-11 21:10:19 +04:00
struct lvinfo info ;
2004-05-05 16:03:07 +04:00
int active = 0 ;
2012-08-06 20:01:01 +04:00
int32_t major , minor ;
2002-02-25 15:56:16 +03:00
2002-02-12 00:00:35 +03:00
if ( ! strcmp ( arg_str_value ( cmd , persistent_ARG , " n " ) , " n " ) ) {
2002-02-01 20:54:39 +03:00
if ( ! ( lv - > status & FIXED_MINOR ) ) {
log_error ( " Minor number is already not persistent "
" for \" %s \" " , lv - > name ) ;
return 0 ;
}
lv - > status & = ~ FIXED_MINOR ;
lv - > minor = - 1 ;
2003-04-02 23:14:43 +04:00
lv - > major = - 1 ;
log_verbose ( " Disabling persistent device number for \" %s \" " ,
lv - > name ) ;
2002-02-01 20:54:39 +03:00
} else {
2003-04-02 23:14:43 +04:00
if ( ! arg_count ( cmd , minor_ARG ) & & lv - > minor < 0 ) {
2002-02-01 20:54:39 +03:00
log_error ( " Minor number must be specified with -My " ) ;
return 0 ;
}
2012-03-06 06:30:49 +04:00
if ( arg_count ( cmd , major_ARG ) > 1 ) {
log_error ( " Option -j/--major may not be repeated. " ) ;
return 0 ;
}
if ( arg_count ( cmd , minor_ARG ) > 1 ) {
log_error ( " Option --minor may not be repeated. " ) ;
return 0 ;
}
2003-04-02 23:14:43 +04:00
if ( ! arg_count ( cmd , major_ARG ) & & lv - > major < 0 ) {
log_error ( " Major number must be specified with -My " ) ;
return 0 ;
}
2010-08-17 20:25:32 +04:00
if ( lv_info ( cmd , lv , 0 , & info , 0 , 0 ) & & info . exists )
2004-05-05 16:03:07 +04:00
active = 1 ;
2012-08-06 20:01:01 +04:00
major = arg_int_value ( cmd , major_ARG , lv - > major ) ;
minor = arg_int_value ( cmd , minor_ARG , lv - > minor ) ;
if ( ! major_minor_valid ( cmd , lv - > vg - > fid - > fmt , major , minor ) )
return 0 ;
2006-10-14 01:33:31 +04:00
if ( active & & ! arg_count ( cmd , force_ARG ) & &
yes_no_prompt ( " Logical volume %s will be "
" deactivated temporarily. "
" Continue? [y/n]: " , lv - > name ) = = ' n ' ) {
2009-12-03 22:18:33 +03:00
log_error ( " %s device number not changed. " ,
2006-10-14 01:33:31 +04:00
lv - > name ) ;
return 0 ;
2003-07-11 21:10:19 +04:00
}
2007-06-15 14:11:14 +04:00
if ( sigint_caught ( ) )
return 0 ;
2004-05-05 22:27:56 +04:00
log_verbose ( " Ensuring %s is inactive. " , lv - > name ) ;
2005-08-15 16:00:04 +04:00
if ( ! deactivate_lv ( cmd , lv ) ) {
2002-03-11 22:02:28 +03:00
log_error ( " %s: deactivation failed " , lv - > name ) ;
return 0 ;
}
2002-02-01 20:54:39 +03:00
lv - > status | = FIXED_MINOR ;
2012-08-06 20:01:01 +04:00
lv - > minor = minor ;
lv - > major = major ;
2003-04-02 23:14:43 +04:00
log_verbose ( " Setting persistent device number to (%d, %d) "
" for \" %s \" " , lv - > major , lv - > minor , lv - > name ) ;
2006-07-10 23:39:14 +04:00
2002-02-01 20:54:39 +03:00
}
2003-07-05 02:34:56 +04:00
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
2009-04-21 18:31:57 +04:00
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2003-07-05 02:34:56 +04:00
backup ( lv - > vg ) ;
2006-07-10 23:39:14 +04:00
if ( active ) {
log_verbose ( " Re-activating logical volume \" %s \" " , lv - > name ) ;
if ( ! activate_lv ( cmd , lv ) ) {
log_error ( " %s: reactivation failed " , lv - > name ) ;
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
2011-01-24 16:38:31 +03:00
static int lvchange_tag ( struct cmd_context * cmd , struct logical_volume * lv , int arg )
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
log_very_verbose ( " Updating logical volume \" %s \" on disk(s) " , lv - > name ) ;
/* No need to suspend LV for this change */
2009-04-21 18:31:57 +04:00
if ( ! vg_write ( lv - > vg ) | | ! vg_commit ( lv - > vg ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2004-03-08 20:19:15 +03:00
2009-04-21 18:31:57 +04:00
backup ( lv - > vg ) ;
2004-03-08 20:19:15 +03:00
return 1 ;
}
2005-03-22 01:55:12 +03:00
2002-11-18 17:04:08 +03:00
static int lvchange_single ( struct cmd_context * cmd , struct logical_volume * lv ,
2010-07-09 19:34:40 +04:00
void * handle __attribute__ ( ( unused ) ) )
2002-11-18 17:04:08 +03:00
{
2008-07-31 17:03:01 +04:00
int doit = 0 , docmds = 0 ;
2012-02-15 19:18:43 +04:00
int archived = 0 ;
2009-05-27 22:19:21 +04:00
struct logical_volume * origin ;
2011-11-18 23:22:49 +04:00
char snaps_msg [ 128 ] ;
2002-11-18 17:04:08 +03:00
if ( ! ( lv - > vg - > status & LVM_WRITE ) & &
( arg_count ( cmd , contiguous_ARG ) | | arg_count ( cmd , permission_ARG ) | |
2004-05-19 02:12:53 +04:00
arg_count ( cmd , readahead_ARG ) | | arg_count ( cmd , persistent_ARG ) | |
2012-08-08 00:24:41 +04:00
arg_count ( cmd , discards_ARG ) | |
2012-06-28 16:52:23 +04:00
arg_count ( cmd , zero_ARG ) | |
2004-05-19 02:12:53 +04:00
arg_count ( cmd , alloc_ARG ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " Only -a permitted with read-only volume "
" group \" %s \" " , lv - > vg - > name ) ;
return EINVALID_CMD_LINE ;
}
if ( lv_is_origin ( lv ) & &
( arg_count ( cmd , contiguous_ARG ) | | arg_count ( cmd , permission_ARG ) | |
2004-05-19 02:12:53 +04:00
arg_count ( cmd , readahead_ARG ) | | arg_count ( cmd , persistent_ARG ) | |
arg_count ( cmd , alloc_ARG ) ) ) {
2002-11-18 17:04:08 +03:00
log_error ( " Can't change logical volume \" %s \" under snapshot " ,
lv - > name ) ;
return ECMD_FAILED ;
}
2011-11-18 23:22:49 +04:00
if ( lv_is_cow ( lv ) & & ! lv_is_virtual_origin ( origin = origin_from_cow ( lv ) ) & &
2012-06-27 15:48:31 +04:00
arg_count ( cmd , activate_ARG ) ) {
2011-11-18 23:22:49 +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 ;
}
if ( ! arg_count ( cmd , yes_ARG ) & &
( yes_no_prompt ( " Change of snapshot %s will also change its "
" origin %s%s. Proceed? [y/n]: " , lv - > name ,
origin - > name , snaps_msg ) = = ' n ' ) ) {
log_error ( " Logical volume %s not changed. " , lv - > name ) ;
return ECMD_FAILED ;
}
2002-11-18 17:04:08 +03:00
}
2003-05-06 16:14:36 +04:00
if ( lv - > status & PVMOVE ) {
log_error ( " Unable to change pvmove LV %s " , lv - > name ) ;
2012-06-27 15:48:31 +04:00
if ( arg_count ( cmd , activate_ARG ) )
2003-05-06 16:14:36 +04:00
log_error ( " Use 'pvmove --abort' to abandon a pvmove " ) ;
return ECMD_FAILED ;
}
2005-06-01 20:51:55 +04:00
if ( lv - > status & MIRROR_LOG ) {
log_error ( " Unable to change mirror log LV %s directly " , lv - > name ) ;
return ECMD_FAILED ;
}
2005-06-03 18:49:51 +04:00
if ( lv - > status & MIRROR_IMAGE ) {
log_error ( " Unable to change mirror image LV %s directly " ,
lv - > name ) ;
return ECMD_FAILED ;
}
2009-05-27 22:19:21 +04:00
/* If LV is sparse, activate origin instead */
2012-06-27 15:48:31 +04:00
if ( arg_count ( cmd , activate_ARG ) & & lv_is_cow ( lv ) & &
2009-05-27 22:19:21 +04:00
lv_is_virtual_origin ( origin = origin_from_cow ( lv ) ) )
lv = origin ;
if ( ! ( lv_is_visible ( lv ) ) & & ! lv_is_virtual_origin ( lv ) ) {
2005-06-03 18:49:51 +04:00
log_error ( " Unable to change internal LV %s directly " ,
lv - > name ) ;
return ECMD_FAILED ;
}
2010-01-06 22:08:58 +03:00
/*
* FIXME : DEFAULT_BACKGROUND_POLLING should be " unspecified " .
* If - - poll is explicitly provided use it ; otherwise polling
* should only be started if the LV is not already active . So :
* 1 ) change the activation code to say if the LV was actually activated
* 2 ) make polling of an LV tightly coupled with LV activation
2010-05-06 15:15:55 +04:00
*
* Do not initiate any polling if - - sysinit option is used .
2010-01-06 22:08:58 +03:00
*/
2010-05-06 15:15:55 +04:00
init_background_polling ( arg_count ( cmd , sysinit_ARG ) ? 0 :
arg_int_value ( cmd , poll_ARG ,
DEFAULT_BACKGROUND_POLLING ) ) ;
2010-01-05 23:56:51 +03:00
2002-11-18 17:04:08 +03:00
/* access permission change */
if ( arg_count ( cmd , permission_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archive ( lv - > vg ) ) {
stack ;
2002-11-18 17:04:08 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2002-11-18 17:04:08 +03:00
archived = 1 ;
doit + = lvchange_permission ( cmd , lv ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2002-11-18 17:04:08 +03:00
}
/* allocation policy change */
2004-05-19 02:12:53 +04:00
if ( arg_count ( cmd , contiguous_ARG ) | | arg_count ( cmd , alloc_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
2002-11-18 17:04:08 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2002-11-18 17:04:08 +03:00
archived = 1 ;
2004-05-19 02:12:53 +04:00
doit + = lvchange_alloc ( cmd , lv ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2002-11-18 17:04:08 +03:00
}
/* read ahead sector change */
if ( arg_count ( cmd , readahead_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
2002-11-18 17:04:08 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2002-11-18 17:04:08 +03:00
archived = 1 ;
doit + = lvchange_readahead ( cmd , lv ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2002-11-18 17:04:08 +03:00
}
2009-11-04 15:39:56 +03:00
/* persistent device number change */
2002-11-18 17:04:08 +03:00
if ( arg_count ( cmd , persistent_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
2002-11-18 17:04:08 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2002-11-18 17:04:08 +03:00
archived = 1 ;
doit + = lvchange_persistent ( cmd , lv ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2009-09-15 02:47:49 +04:00
if ( sigint_caught ( ) ) {
stack ;
2007-06-15 14:11:14 +04:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2002-11-18 17:04:08 +03:00
}
2012-08-08 00:24:41 +04:00
if ( arg_count ( cmd , discards_ARG ) | |
2012-06-28 16:52:23 +04:00
arg_count ( cmd , zero_ARG ) ) {
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
return ECMD_FAILED ;
}
archived = 1 ;
doit + = lvchange_pool_update ( cmd , lv ) ;
docmds + + ;
}
2004-03-08 20:19:15 +03:00
/* add tag */
if ( arg_count ( cmd , addtag_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
2004-03-08 20:19:15 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2004-03-08 20:19:15 +03:00
archived = 1 ;
doit + = lvchange_tag ( cmd , lv , addtag_ARG ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2004-03-08 20:19:15 +03:00
}
/* del tag */
if ( arg_count ( cmd , deltag_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! archived & & ! archive ( lv - > vg ) ) {
stack ;
2004-03-08 20:19:15 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2004-03-08 20:19:15 +03:00
archived = 1 ;
doit + = lvchange_tag ( cmd , lv , deltag_ARG ) ;
2008-07-31 17:03:01 +04:00
docmds + + ;
2004-03-08 20:19:15 +03:00
}
2002-11-18 17:04:08 +03:00
if ( doit )
config: add silent mode
Accept -q as the short form of --quiet.
Suppress non-essential standard output if -q is given twice.
Treat log/silent in lvm.conf as equivalent to -qq.
Review all log_print messages and change some to
log_print_unless_silent.
When silent, the following commands still produce output:
dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay,
pvs, version, vgcfgrestore -l, vgdisplay, vgs.
[Needs checking.]
Non-essential messages are shifted from log level 4 to log level 5
for syslog and lvm2_log_fn purposes.
2012-08-25 23:35:48 +04:00
log_print_unless_silent ( " Logical volume \" %s \" changed " , lv - > name ) ;
2002-11-18 17:04:08 +03:00
2006-10-24 21:18:25 +04:00
if ( arg_count ( cmd , resync_ARG ) )
2009-09-15 02:47:49 +04:00
if ( ! lvchange_resync ( cmd , lv ) ) {
stack ;
2006-10-24 03:03:55 +04:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2006-10-24 03:03:55 +04:00
2012-06-27 15:48:31 +04:00
/* activation change */
if ( arg_count ( cmd , activate_ARG ) ) {
if ( ! _lvchange_activate ( cmd , lv ) ) {
2009-09-15 02:47:49 +04:00
stack ;
2002-11-18 17:04:08 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2006-05-12 23:16:48 +04:00
}
2002-11-18 17:04:08 +03:00
2004-03-27 00:24:03 +03:00
if ( arg_count ( cmd , refresh_ARG ) )
2009-09-15 02:47:49 +04:00
if ( ! lvchange_refresh ( cmd , lv ) ) {
stack ;
2004-03-27 00:24:03 +03:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2004-03-27 00:24:03 +03:00
2012-06-27 15:48:31 +04:00
if ( ! arg_count ( cmd , activate_ARG ) & &
2006-05-12 23:16:48 +04:00
! arg_count ( cmd , refresh_ARG ) & &
arg_count ( cmd , monitor_ARG ) ) {
2009-09-15 02:47:49 +04:00
if ( ! lvchange_monitoring ( cmd , lv ) ) {
stack ;
2006-05-12 23:16:48 +04:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
2006-05-12 23:16:48 +04:00
}
2012-06-27 15:48:31 +04:00
if ( ! arg_count ( cmd , activate_ARG ) & &
2010-01-05 23:56:51 +03:00
! arg_count ( cmd , refresh_ARG ) & &
arg_count ( cmd , poll_ARG ) ) {
if ( ! lvchange_background_polling ( cmd , lv ) ) {
stack ;
return ECMD_FAILED ;
}
}
2009-09-15 02:47:49 +04:00
if ( doit ! = docmds ) {
stack ;
2008-07-31 17:03:01 +04:00
return ECMD_FAILED ;
2009-09-15 02:47:49 +04:00
}
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
}
int lvchange ( struct cmd_context * cmd , int argc , char * * argv )
{
2010-10-26 05:37:59 +04:00
int update = /* options other than -a, --refresh, --monitor or --poll */
2010-06-28 23:10:16 +04:00
arg_count ( cmd , contiguous_ARG ) | | arg_count ( cmd , permission_ARG ) | |
arg_count ( cmd , readahead_ARG ) | | arg_count ( cmd , persistent_ARG ) | |
arg_count ( cmd , addtag_ARG ) | | arg_count ( cmd , deltag_ARG ) | |
2012-06-28 16:52:23 +04:00
arg_count ( cmd , resync_ARG ) | | arg_count ( cmd , alloc_ARG ) | |
2012-08-08 00:24:41 +04:00
arg_count ( cmd , discards_ARG ) | | arg_count ( cmd , zero_ARG ) ;
2010-06-28 23:10:16 +04:00
if ( ! update & &
2012-06-27 15:48:31 +04:00
! arg_count ( cmd , activate_ARG ) & & ! arg_count ( cmd , refresh_ARG ) & &
2011-09-05 16:54:29 +04:00
! arg_count ( cmd , monitor_ARG ) & & ! arg_count ( cmd , poll_ARG ) ) {
2012-08-07 23:08:14 +04:00
log_error ( " Need 1 or more of -a, -C, -M, -p, -r, -Z, "
2010-01-05 23:56:51 +03:00
" --resync, --refresh, --alloc, --addtag, --deltag, "
2012-08-08 00:24:41 +04:00
" --monitor, --poll or --discards " ) ;
2002-11-18 17:04:08 +03:00
return EINVALID_CMD_LINE ;
}
2012-06-27 15:48:31 +04:00
if ( arg_count ( cmd , activate_ARG ) & & arg_count ( cmd , refresh_ARG ) ) {
2010-10-26 05:37:59 +04:00
log_error ( " Only one of -a and --refresh permitted. " ) ;
return EINVALID_CMD_LINE ;
}
2009-07-15 09:47:55 +04:00
2010-05-06 15:15:55 +04:00
if ( ( arg_count ( cmd , ignorelockingfailure_ARG ) | |
2010-06-28 23:10:16 +04:00
arg_count ( cmd , sysinit_ARG ) ) & & update ) {
2010-05-06 15:15:55 +04:00
log_error ( " Only -a permitted with --ignorelockingfailure and --sysinit " ) ;
2002-11-18 17:04:08 +03:00
return EINVALID_CMD_LINE ;
}
2010-06-28 23:10:16 +04:00
if ( ! update )
2009-07-15 09:47:55 +04:00
cmd - > handles_missing_pvs = 1 ;
2002-11-18 17:04:08 +03:00
if ( ! argc ) {
log_error ( " Please give logical volume path(s) " ) ;
return EINVALID_CMD_LINE ;
}
2003-04-02 23:14:43 +04:00
if ( ( arg_count ( cmd , minor_ARG ) | | arg_count ( cmd , major_ARG ) ) & &
! arg_count ( cmd , persistent_ARG ) ) {
log_error ( " --major and --minor require -My " ) ;
return EINVALID_CMD_LINE ;
}
2002-11-18 17:04:08 +03:00
if ( arg_count ( cmd , minor_ARG ) & & argc ! = 1 ) {
log_error ( " Only give one logical volume when specifying minor " ) ;
return EINVALID_CMD_LINE ;
}
2004-05-19 02:12:53 +04:00
if ( arg_count ( cmd , contiguous_ARG ) & & arg_count ( cmd , alloc_ARG ) ) {
log_error ( " Only one of --alloc and --contiguous permitted " ) ;
return EINVALID_CMD_LINE ;
}
2010-05-06 15:15:55 +04:00
if ( arg_count ( cmd , poll_ARG ) & & arg_count ( cmd , sysinit_ARG ) ) {
log_error ( " Only one of --poll and --sysinit permitted " ) ;
return EINVALID_CMD_LINE ;
}
2012-07-10 15:49:46 +04:00
if ( arg_count ( cmd , sysinit_ARG ) & & lvmetad_active ( ) & &
arg_uint_value ( cmd , activate_ARG , 0 ) = = CHANGE_AAY ) {
log_warn ( " lvmetad is active while using --sysinit -a ay, "
" skipping manual activation " ) ;
return ECMD_PROCESSED ;
}
2009-07-15 09:48:36 +04:00
return process_each_lv ( cmd , argc , argv ,
2010-06-28 23:10:16 +04:00
update ? READ_FOR_UPDATE : 0 , NULL ,
2002-11-18 17:04:08 +03:00
& lvchange_single ) ;
}