2001-10-03 21:03:25 +04:00
/*
* Copyright ( C ) 2001 Sistina Software
*
* LVM is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* LVM is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with LVM ; see the file COPYING . If not , write to
* the Free Software Foundation , 59 Temple Place - Suite 330 ,
* Boston , MA 02111 - 1307 , USA .
*
*/
# include "tools.h"
void pvchange_single_volume ( struct physical_volume * pv ) ;
int pvchange ( int argc , char * * argv )
{
int back_it_up = 0 ;
int change_msg = 0 ;
int done = 0 ;
int doit = 0 ;
int not_done = 0 ;
int allocation ;
int opt = 0 ;
int ret = 0 ;
char * pv_name ;
char * vg_name ;
struct io_space * ios ;
struct physical_volume * pv = NULL ;
struct volume_group * vg = NULL ;
struct device * pv_dev ;
struct list_head * pvh ;
struct pv_list * pvl , * pvs_list ;
allocation = ! strcmp ( arg_str_value ( allocation_ARG , " n " ) , " y " ) ;
if ( arg_count ( allocation_ARG ) = = 0 ) {
log_error ( " Please give the x option " ) ;
2001-10-05 02:53:37 +04:00
return EINVALID_CMD_LINE ;
2001-10-03 21:03:25 +04:00
}
ios = active_ios ( ) ;
if ( ! ( arg_count ( all_ARG ) ) & & ! argc ) {
log_error ( " Please give a physical volume path " ) ;
2001-10-05 02:53:37 +04:00
return EINVALID_CMD_LINE ;
2001-10-03 21:03:25 +04:00
}
if ( arg_count ( all_ARG ) & & argc ) {
log_error ( " Option a and PhysicalVolumePath are exclusive " ) ;
2001-10-05 02:53:37 +04:00
return EINVALID_CMD_LINE ;
2001-10-03 21:03:25 +04:00
}
if ( arg_count ( all_ARG ) ) {
log_verbose ( " Scanning for physical volume names " ) ;
if ( ! ( pvs_list = ios - > get_pvs ( ios ) ) ) {
2001-10-05 02:53:37 +04:00
return ECMD_FAILED ;
2001-10-03 21:03:25 +04:00
}
list_for_each ( pvh , & pvs_list - > list ) {
pvl = list_entry ( pvh , struct pv_list , list ) ;
pv = & pvl - > pv ;
pvchange_single_volume ( pv ) ;
}
} else {
for ( ; opt < argc ; opt + + ) {
pv_name = argv [ opt ] ;
if ( ! ( pv_dev = dev_cache_get ( pv_name ) ) ) {
log_error ( " Device %s not found " , pv_name ) ;
continue ;
}
if ( ! ( pv = ios - > pv_read ( ios , pv_dev ) ) ) {
log_error ( " Failed to read physical volume %s " ,
pv_name ) ;
continue ;
}
pvchange_single_volume ( pv ) ;
}
}
if ( back_it_up )
if ( ( ret = do_autobackup ( vg_name , vg ) ) )
return ret ;
log_print ( " %d physical volume%s changed / %d physical volume%s "
" already o.k. " , done , done ! = 1 ? " s " : " " , not_done ,
not_done ! = 1 ? " s " : " " ) ;
return 0 ;
}
void pvchange_single_volume ( struct physical_volume * pv )
{
struct volume_group * vg ;
change_msg = 0 ;
/* FIXME: Check these verbose messages appear in the library now */
/* log_verbose("reading physical volume data %s from disk", pv_name); */
/* FIXME: Ensure these are tested in the library */
/* log_error("physical volume %s has an invalid version", pv_name); */
/* log_error("physical volume %s has invalid identity", pv_name); */
/* FIXME: Where do consistency checks fit? */
/* log_verbose("checking physical volume %s consistency", pv_name); */
/* FIXME: Does the VG really have to be active to proceed? */
log_verbose ( " finding volume group of physical volume %s " , pv_name ) ;
if ( ! ( vg = ios - > vg_read ( ios , pv - > vg_name ) ) ) {
log_print ( " unable to find volume group of %s (VG not active?) " ,
pv - > dev - > name ) ;
doit = 0 ;
return ;
}
back_it_up = doit = 1 ;
/* change allocatability for a PV */
if ( arg_count ( allocation_ARG ) > 0 ) {
2001-10-06 01:39:30 +04:00
if ( allocation & & ( pv - > status & ALLOCATED_PV ) ) {
2001-10-03 21:03:25 +04:00
log_error ( " physical volume %s is allocatable " , pv_name ) ;
not_done + + ;
return ;
} else
change_msg = 1 ;
2001-10-06 01:39:30 +04:00
if ( ! allocation & & ! ( pv - > status & ALLOCATED_PV ) ) {
2001-10-03 21:03:25 +04:00
log_error ( " physical volume %s is unallocatable " ,
pv_name ) ;
not_done + + ;
return ;
} else
change_msg = 1 ;
if ( allocation ) {
log_verbose
( " setting physical volume %s allocatable " , pv_name ) ;
2001-10-06 01:39:30 +04:00
pv - > status | = ALLOCATED_PV ;
2001-10-03 21:03:25 +04:00
} else {
log_verbose
( " setting physical volume %s NOT allocatable " ,
pv_name ) ;
2001-10-06 01:39:30 +04:00
pv - > status & = ~ ALLOCATED_PV ;
2001-10-03 21:03:25 +04:00
}
}
done + + ;
if ( doit = = 1 ) {
log_verbose ( " checking physical volume %s is activite " ,
pv - > dev - > name ) ;
2001-10-06 01:39:30 +04:00
if ( ! ( pv - > status & ACTIVE ) ) {
2001-10-03 21:03:25 +04:00
log_verbose ( " Physical volume %s inactive " , pv_name ) ;
}
log_verbose ( " Updating physical volume %s " , pv - > dev - > name ) ;
if ( ! ( ios - > pv_write ( ios , pv ) ) ) {
log_error
( " Failed to store physical volume %s " ,
pv - > dev - > name ) ;
/* Abort completely here? */
return LVM_E_PV_WRITE ;
}
log_print ( " physical volume %s %s changed " , pv_name ,
( change_msg ) ? " " : " not " ) ;
}
}