2001-10-03 21:03:25 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2015-02-12 19:37:47 +03:00
* Copyright ( C ) 2004 - 2015 Red Hat , Inc . All rights reserved .
2001-10-03 21:03:25 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2001-10-03 21:03:25 +04: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-03 21:03:25 +04: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-03 21:03:25 +04:00
*/
# include "tools.h"
2015-02-12 19:37:47 +03:00
struct pvchange_params {
unsigned done ;
unsigned total ;
} ;
2010-05-19 15:53:00 +04:00
static int _pvchange_single ( struct cmd_context * cmd , struct volume_group * vg ,
2015-02-12 19:37:47 +03:00
struct physical_volume * pv , struct processing_handle * handle )
2001-10-03 21:03:25 +04:00
{
2015-02-12 19:37:47 +03:00
struct pvchange_params * params = ( struct pvchange_params * ) handle - > custom_handle ;
2007-10-12 18:29:32 +04:00
const char * pv_name = pv_dev_name ( pv ) ;
2010-07-09 19:34:40 +04:00
char uuid [ 64 ] __attribute__ ( ( aligned ( 8 ) ) ) ;
2015-02-12 19:37:47 +03:00
unsigned done = 0 ;
2001-10-03 21:03:25 +04:00
2014-10-11 20:17:46 +04:00
int allocatable = arg_int_value ( cmd , allocatable_ARG , 0 ) ;
int mda_ignore = arg_int_value ( cmd , metadataignore_ARG , 0 ) ;
int tagargs = arg_count ( cmd , addtag_ARG ) + arg_count ( cmd , deltag_ARG ) ;
2001-10-03 21:03:25 +04:00
2015-02-12 19:37:47 +03:00
params - > total + + ;
2002-01-29 20:23:33 +03:00
/* If in a VG, must change using volume group. */
2007-11-02 17:54:40 +03:00
if ( ! is_orphan ( pv ) ) {
2011-01-24 16:38:31 +03:00
if ( tagargs & & ! ( vg - > fid - > fmt - > features & FMT_TAGS ) ) {
2004-03-08 20:19:15 +03:00
log_error ( " Volume group containing %s does not "
" support tags " , pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2004-03-08 20:19:15 +03:00
}
2004-01-13 21:42:05 +03:00
if ( arg_count ( cmd , uuid_ARG ) & & lvs_in_vg_activated ( vg ) ) {
log_error ( " Volume group containing %s has active "
" logical volumes " , pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2004-01-13 21:42:05 +03:00
}
2002-01-09 16:17:14 +03:00
if ( ! archive ( vg ) )
2015-02-12 19:37:47 +03:00
goto_bad ;
} else if ( tagargs ) {
log_error ( " Can't change tag on Physical Volume %s not "
" in volume group " , pv_name ) ;
goto bad ;
2001-10-17 19:29:31 +04:00
}
2001-10-03 21:03:25 +04:00
2004-01-13 21:42:05 +03:00
if ( arg_count ( cmd , allocatable_ARG ) ) {
2007-11-02 17:54:40 +03:00
if ( is_orphan ( pv ) & &
2004-01-13 21:42:05 +03:00
! ( pv - > fmt - > features & FMT_ORPHAN_ALLOCATABLE ) ) {
log_error ( " Allocatability not supported by orphan "
" %s format PV %s " , pv - > fmt - > name , pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2004-01-13 21:42:05 +03:00
}
2001-10-03 21:03:25 +04:00
2004-01-13 21:42:05 +03:00
/* change allocatability for a PV */
2007-06-16 02:16:55 +04:00
if ( allocatable & & ( pv_status ( pv ) & ALLOCATABLE_PV ) ) {
2012-10-16 12:14:41 +04:00
log_warn ( " Physical volume \" %s \" is already "
" allocatable. " , pv_name ) ;
2015-02-12 19:37:47 +03:00
} else if ( ! allocatable & & ! ( pv_status ( pv ) & ALLOCATABLE_PV ) ) {
2012-10-16 12:14:41 +04:00
log_warn ( " Physical volume \" %s \" is already "
" unallocatable. " , pv_name ) ;
2015-02-12 19:37:47 +03:00
} else if ( allocatable ) {
2004-01-13 21:42:05 +03:00
log_verbose ( " Setting physical volume \" %s \" "
" allocatable " , pv_name ) ;
pv - > status | = ALLOCATABLE_PV ;
2015-02-12 19:37:47 +03:00
done = 1 ;
2004-01-13 21:42:05 +03:00
} else {
log_verbose ( " Setting physical volume \" %s \" NOT "
" allocatable " , pv_name ) ;
pv - > status & = ~ ALLOCATABLE_PV ;
2015-02-12 19:37:47 +03:00
done = 1 ;
2004-01-13 21:42:05 +03:00
}
2011-01-24 16:38:31 +03:00
}
2010-11-11 20:29:05 +03:00
2015-03-05 23:00:44 +03:00
/*
* Needed to change a property on an orphan PV .
* i . e . the global lock is only needed for orphans .
* Convert sh to ex .
*/
if ( is_orphan ( pv ) & & ! lockd_gl ( cmd , " ex " , 0 ) )
return_ECMD_FAILED ;
2011-01-24 16:38:31 +03:00
if ( tagargs ) {
/* tag or deltag */
if ( arg_count ( cmd , addtag_ARG ) & & ! change_tag ( cmd , NULL , NULL , pv , addtag_ARG ) )
2015-02-12 19:37:47 +03:00
goto_bad ;
2010-11-11 20:29:05 +03:00
2011-01-24 16:38:31 +03:00
if ( arg_count ( cmd , deltag_ARG ) & & ! change_tag ( cmd , NULL , NULL , pv , deltag_ARG ) )
2015-02-12 19:37:47 +03:00
goto_bad ;
done = 1 ;
2011-01-24 16:38:31 +03:00
}
2010-11-11 20:29:05 +03:00
2011-01-24 16:38:31 +03:00
if ( arg_count ( cmd , metadataignore_ARG ) ) {
2010-07-07 23:02:50 +04:00
if ( ( vg_mda_copies ( vg ) ! = VGMETADATACOPIES_UNMANAGED ) & &
2010-07-07 23:14:57 +04:00
( arg_count ( cmd , force_ARG ) = = PROMPT ) & &
2010-07-08 01:30:07 +04:00
yes_no_prompt ( " Override preferred number of copies "
" of VG %s metadata? [y/n]: " ,
2015-02-12 19:37:47 +03:00
pv_vg_name ( pv ) ) = = ' n ' )
goto_bad ;
2010-06-30 01:32:44 +04:00
if ( ! pv_change_metadataignore ( pv , mda_ignore ) )
2015-02-12 19:37:47 +03:00
goto_bad ;
done = 1 ;
2011-01-24 16:38:31 +03:00
}
if ( arg_count ( cmd , uuid_ARG ) ) {
2004-01-13 21:42:05 +03:00
/* --uuid: Change PV ID randomly */
2011-02-21 15:31:28 +03:00
memcpy ( & pv - > old_id , & pv - > id , sizeof ( pv - > id ) ) ;
2005-01-20 21:11:53 +03:00
if ( ! id_create ( & pv - > id ) ) {
log_error ( " Failed to generate new random UUID for %s. " ,
pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2005-05-24 21:38:26 +04:00
}
2009-04-10 14:01:38 +04:00
if ( ! id_write_format ( & pv - > id , uuid , sizeof ( uuid ) ) )
2015-02-12 19:37:47 +03:00
goto_bad ;
2005-05-24 21:38:26 +04:00
log_verbose ( " Changing uuid of %s to %s. " , pv_name , uuid ) ;
2013-03-25 17:30:40 +04:00
if ( ! is_orphan ( pv ) & & ( ! pv_write ( cmd , pv , 1 ) ) ) {
log_error ( " pv_write with new uuid failed "
" for %s. " , pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2005-05-24 21:38:26 +04:00
}
2015-02-12 19:37:47 +03:00
done = 1 ;
}
if ( ! done ) {
log_print_unless_silent ( " Physical volume %s not changed " , pv_name ) ;
return ECMD_PROCESSED ;
2001-10-03 21:03:25 +04:00
}
2002-01-30 18:04:48 +03:00
log_verbose ( " Updating physical volume \" %s \" " , pv_name ) ;
2007-11-02 17:54:40 +03:00
if ( ! is_orphan ( pv ) ) {
2003-07-05 02:34:56 +04:00
if ( ! vg_write ( vg ) | | ! vg_commit ( vg ) ) {
2002-01-30 18:04:48 +03:00
log_error ( " Failed to store physical volume \" %s \" in "
" volume group \" %s \" " , pv_name , vg - > name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2001-10-03 21:03:25 +04:00
}
2002-01-07 14:12:11 +03:00
backup ( vg ) ;
2011-02-28 16:19:02 +03:00
} else if ( ! ( pv_write ( cmd , pv , 0 ) ) ) {
2007-11-02 23:40:05 +03:00
log_error ( " Failed to store physical volume \" %s \" " ,
pv_name ) ;
2015-02-12 19:37:47 +03:00
goto bad ;
2001-10-03 21:03:25 +04:00
}
2001-10-17 19:29:31 +04:00
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 ( " Physical volume \" %s \" changed " , pv_name ) ;
2001-10-17 19:29:31 +04:00
2015-02-12 19:37:47 +03:00
params - > done + + ;
return ECMD_PROCESSED ;
bad :
log_error ( " Physical volume %s not changed " , pv_name ) ;
return ECMD_FAILED ;
2001-10-03 21:03:25 +04:00
}
2002-11-18 17:04:08 +03:00
int pvchange ( struct cmd_context * cmd , int argc , char * * argv )
{
2015-02-12 19:37:47 +03:00
struct pvchange_params params = { 0 } ;
2014-12-03 12:02:13 +03:00
struct processing_handle * handle = NULL ;
2015-02-19 16:03:45 +03:00
int ret ;
2014-12-03 12:02:13 +03:00
2011-01-24 16:38:31 +03:00
if ( ! ( arg_count ( cmd , allocatable_ARG ) + arg_is_set ( cmd , addtag_ARG ) +
2010-11-11 20:29:05 +03:00
arg_is_set ( cmd , deltag_ARG ) + arg_count ( cmd , uuid_ARG ) +
2011-01-24 16:38:31 +03:00
arg_count ( cmd , metadataignore_ARG ) ) ) {
log_error ( " Please give one or more of -x, -uuid, "
" --addtag, --deltag or --metadataignore " ) ;
2015-02-12 19:37:47 +03:00
ret = EINVALID_CMD_LINE ;
2014-12-03 12:02:13 +03:00
goto out ;
}
2015-02-13 11:28:24 +03:00
if ( ! ( handle = init_processing_handle ( cmd ) ) ) {
2014-12-03 12:02:13 +03:00
log_error ( " Failed to initialize processing handle. " ) ;
2015-02-12 19:37:47 +03:00
ret = ECMD_FAILED ;
2014-12-03 12:02:13 +03:00
goto out ;
2002-11-18 17:04:08 +03:00
}
2015-02-12 19:37:47 +03:00
handle - > custom_handle = & params ;
2014-12-03 12:02:13 +03:00
if ( ! ( arg_count ( cmd , all_ARG ) ) & & ! argc & & ! handle - > internal_report_for_select ) {
2015-03-04 16:40:04 +03:00
log_error ( " Please give a physical volume path or use --select for selection. " ) ;
2015-02-12 19:37:47 +03:00
ret = EINVALID_CMD_LINE ;
2014-12-03 12:02:13 +03:00
goto out ;
2002-11-18 17:04:08 +03:00
}
if ( arg_count ( cmd , all_ARG ) & & argc ) {
2014-05-22 01:10:35 +04:00
log_error ( " Option --all and PhysicalVolumePath are exclusive. " ) ;
2015-02-12 19:37:47 +03:00
ret = EINVALID_CMD_LINE ;
2014-12-03 12:02:13 +03:00
goto out ;
2002-11-18 17:04:08 +03:00
}
2015-02-12 19:37:47 +03:00
if ( ! argc ) {
2010-05-19 15:53:00 +04:00
/*
* Take the global lock here so the lvmcache remains
* consistent across orphan / non - orphan vg locks . If we don ' t
* take the lock here , pvs with 0 mdas in a non - orphan VG will
* be processed twice .
*/
2013-03-18 00:29:58 +04:00
if ( ! lock_vol ( cmd , VG_GLOBAL , LCK_VG_WRITE , NULL ) ) {
2010-05-19 15:53:00 +04:00
log_error ( " Unable to obtain global lock. " ) ;
2015-02-12 19:37:47 +03:00
ret = ECMD_FAILED ;
2014-12-03 12:02:13 +03:00
goto out ;
2002-11-18 17:04:08 +03:00
}
2015-02-12 19:37:47 +03:00
}
2002-11-18 17:04:08 +03:00
2015-02-12 19:37:47 +03:00
ret = process_each_pv ( cmd , argc , argv , NULL , READ_FOR_UPDATE , handle , _pvchange_single ) ;
if ( ! argc )
2010-12-23 17:23:30 +03:00
unlock_vg ( cmd , VG_GLOBAL ) ;
2002-11-18 17:04:08 +03:00
2015-02-12 19:37:47 +03:00
log_print_unless_silent ( " %d physical volume%s changed / %d physical volume%s not changed " ,
params . done , params . done = = 1 ? " " : " s " ,
params . total - params . done , ( params . total - params . done ) = = 1 ? " " : " s " ) ;
2002-11-18 17:04:08 +03:00
2014-12-03 12:02:13 +03:00
out :
2015-02-13 12:42:21 +03:00
destroy_processing_handle ( cmd , handle ) ;
2015-02-12 19:37:47 +03:00
return ret ;
2002-11-18 17:04:08 +03:00
}