2001-10-01 19:29:39 +04:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2001-11-07 11:50:07 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2001-11-07 11:50:07 +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-11-07 11:50:07 +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-01 19:29:39 +04:00
*/
# include "tools.h"
2009-07-26 05:53:09 +04:00
# include "metadata-exported.h"
2001-10-01 19:29:39 +04:00
2008-07-21 23:26:33 +04:00
/*
2008-07-21 23:27:22 +04:00
* Intial sanity checking of command - line arguments and fill in ' pp ' fields .
*
* Input arguments :
* cmd , argc , argv
*
* Output arguments :
* pp : structure allocated by caller , fields written / validated here
2008-07-21 23:26:33 +04:00
*/
2008-07-21 23:27:22 +04:00
static int pvcreate_validate_params ( struct cmd_context * cmd ,
int argc , char * * argv ,
struct pvcreate_params * pp )
2001-10-12 14:32:06 +04:00
{
2008-07-25 04:30:57 +04:00
const char * uuid = NULL ;
void * existing_pv ;
struct volume_group * vg ;
memset ( pp , 0 , sizeof ( * pp ) ) ;
2001-10-12 14:32:06 +04:00
if ( ! argc ) {
log_error ( " Please enter a physical volume path " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2001-10-12 14:32:06 +04:00
}
2001-10-01 19:29:39 +04:00
2002-11-18 17:04:08 +03:00
if ( arg_count ( cmd , restorefile_ARG ) & & ! arg_count ( cmd , uuidstr_ARG ) ) {
log_error ( " --uuid is required with --restorefile " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2002-11-18 17:04:08 +03:00
}
2002-02-12 00:00:35 +03:00
if ( arg_count ( cmd , uuidstr_ARG ) & & argc ! = 1 ) {
2002-01-16 21:10:08 +03:00
log_error ( " Can only set uuid on one volume at once " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2002-01-16 21:10:08 +03:00
}
2008-07-25 04:30:57 +04:00
if ( arg_count ( cmd , uuidstr_ARG ) ) {
uuid = arg_str_value ( cmd , uuidstr_ARG , " " ) ;
if ( ! id_read_format ( & pp - > id , uuid ) )
return 0 ;
pp - > idp = & pp - > id ;
}
if ( arg_count ( cmd , restorefile_ARG ) ) {
pp - > restorefile = arg_str_value ( cmd , restorefile_ARG , " " ) ;
/* The uuid won't already exist */
if ( ! ( vg = backup_read_vg ( cmd , NULL , pp - > restorefile ) ) ) {
log_error ( " Unable to read volume group from %s " ,
pp - > restorefile ) ;
return 0 ;
}
if ( ! ( existing_pv = find_pv_in_vg_by_uuid ( vg , pp - > idp ) ) ) {
log_error ( " Can't find uuid %s in backup file %s " ,
uuid , pp - > restorefile ) ;
return 0 ;
}
pp - > pe_start = pv_pe_start ( existing_pv ) ;
pp - > extent_size = pv_pe_size ( existing_pv ) ;
pp - > extent_count = pv_pe_count ( existing_pv ) ;
2009-04-10 14:01:38 +04:00
vg_release ( vg ) ;
2008-07-25 04:30:57 +04:00
}
2002-02-12 00:00:35 +03:00
if ( arg_count ( cmd , yes_ARG ) & & ! arg_count ( cmd , force_ARG ) ) {
2001-10-12 16:21:43 +04:00
log_error ( " Option y can only be given with option f " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2001-10-01 19:29:39 +04:00
}
2008-07-25 18:45:24 +04:00
pp - > yes = arg_count ( cmd , yes_ARG ) ;
2008-07-25 18:36:55 +04:00
pp - > force = arg_count ( cmd , force_ARG ) ;
2002-11-18 17:04:08 +03:00
if ( arg_int_value ( cmd , labelsector_ARG , 0 ) > = LABEL_SCAN_SECTORS ) {
log_error ( " labelsector must be less than %lu " ,
LABEL_SCAN_SECTORS ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2008-07-23 23:29:58 +04:00
} else {
pp - > labelsector = arg_int64_value ( cmd , labelsector_ARG ,
DEFAULT_LABELSECTOR ) ;
2002-11-18 17:04:08 +03:00
}
if ( ! ( cmd - > fmt - > features & FMT_MDAS ) & &
( arg_count ( cmd , metadatacopies_ARG ) | |
2009-02-22 22:00:26 +03:00
arg_count ( cmd , metadatasize_ARG ) | |
2009-07-30 21:45:28 +04:00
arg_count ( cmd , dataalignment_ARG ) | |
arg_count ( cmd , dataalignmentoffset_ARG ) ) ) {
2009-02-22 22:00:26 +03:00
log_error ( " Metadata and data alignment parameters only "
" apply to text format. " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2002-11-18 17:04:08 +03:00
}
if ( arg_count ( cmd , metadatacopies_ARG ) & &
arg_int_value ( cmd , metadatacopies_ARG , - 1 ) > 2 ) {
log_error ( " Metadatacopies may only be 0, 1 or 2 " ) ;
2008-07-21 23:26:33 +04:00
return 0 ;
2002-11-18 17:04:08 +03:00
}
2005-01-05 20:25:25 +03:00
if ( arg_count ( cmd , zero_ARG ) )
2008-07-21 23:26:33 +04:00
pp - > zero = strcmp ( arg_str_value ( cmd , zero_ARG , " y " ) , " n " ) ;
2005-01-05 20:25:25 +03:00
else if ( arg_count ( cmd , restorefile_ARG ) | | arg_count ( cmd , uuidstr_ARG ) )
2008-07-21 23:26:33 +04:00
pp - > zero = 0 ;
2005-01-05 20:25:25 +03:00
else
2008-07-21 23:26:33 +04:00
pp - > zero = 1 ;
2008-07-21 23:27:22 +04:00
if ( arg_sign_value ( cmd , physicalvolumesize_ARG , 0 ) = = SIGN_MINUS ) {
log_error ( " Physical volume size may not be negative " ) ;
return 0 ;
}
pp - > size = arg_uint64_value ( cmd , physicalvolumesize_ARG , UINT64_C ( 0 ) ) ;
2008-07-21 23:26:33 +04:00
2009-02-22 22:00:26 +03:00
if ( arg_sign_value ( cmd , dataalignment_ARG , 0 ) = = SIGN_MINUS ) {
log_error ( " Physical volume data alignment may not be negative " ) ;
return 0 ;
}
pp - > data_alignment = arg_uint64_value ( cmd , dataalignment_ARG , UINT64_C ( 0 ) ) ;
if ( pp - > data_alignment > ULONG_MAX ) {
log_error ( " Physical volume data alignment is too big. " ) ;
return 0 ;
}
if ( pp - > data_alignment & & pp - > pe_start ) {
if ( pp - > pe_start % pp - > data_alignment )
log_warn ( " WARNING: Ignoring data alignment % " PRIu64
" incompatible with --restorefile value (% "
PRIu64 " ). " , pp - > data_alignment , pp - > pe_start ) ;
pp - > data_alignment = 0 ;
}
2009-07-30 21:45:28 +04:00
if ( arg_sign_value ( cmd , dataalignmentoffset_ARG , 0 ) = = SIGN_MINUS ) {
log_error ( " Physical volume data alignment offset may not be negative " ) ;
return 0 ;
}
pp - > data_alignment_offset = arg_uint64_value ( cmd , dataalignmentoffset_ARG , UINT64_C ( 0 ) ) ;
if ( pp - > data_alignment_offset > ULONG_MAX ) {
log_error ( " Physical volume data alignment offset is too big. " ) ;
return 0 ;
}
if ( pp - > data_alignment_offset & & pp - > pe_start ) {
log_warn ( " WARNING: Ignoring data alignment offset % " PRIu64
" incompatible with --restorefile value (% "
PRIu64 " ). " , pp - > data_alignment_offset , pp - > pe_start ) ;
pp - > data_alignment_offset = 0 ;
}
2008-07-21 23:27:22 +04:00
if ( arg_sign_value ( cmd , metadatasize_ARG , 0 ) = = SIGN_MINUS ) {
log_error ( " Metadata size may not be negative " ) ;
return 0 ;
}
pp - > pvmetadatasize = arg_uint64_value ( cmd , metadatasize_ARG , UINT64_C ( 0 ) ) ;
if ( ! pp - > pvmetadatasize )
pp - > pvmetadatasize = find_config_tree_int ( cmd ,
" metadata/pvmetadatasize " ,
DEFAULT_PVMETADATASIZE ) ;
pp - > pvmetadatacopies = arg_int_value ( cmd , metadatacopies_ARG , - 1 ) ;
if ( pp - > pvmetadatacopies < 0 )
pp - > pvmetadatacopies = find_config_tree_int ( cmd ,
" metadata/pvmetadatacopies " ,
DEFAULT_PVMETADATACOPIES ) ;
2008-07-21 23:26:33 +04:00
return 1 ;
}
int pvcreate ( struct cmd_context * cmd , int argc , char * * argv )
{
2008-07-25 18:59:51 +04:00
int i ;
2008-07-21 23:26:33 +04:00
int ret = ECMD_PROCESSED ;
struct pvcreate_params pp ;
2008-07-21 23:27:22 +04:00
if ( ! pvcreate_validate_params ( cmd , argc , argv , & pp ) ) {
2008-07-21 23:26:33 +04:00
return EINVALID_CMD_LINE ;
}
2001-10-12 14:32:06 +04:00
for ( i = 0 ; i < argc ; i + + ) {
2009-07-26 05:54:20 +04:00
if ( ! lock_vol ( cmd , VG_ORPHANS , LCK_VG_WRITE ) ) {
log_error ( " Can't get lock for orphan PVs " ) ;
return ECMD_FAILED ;
}
2008-07-25 18:59:51 +04:00
if ( ! pvcreate_single ( cmd , argv [ i ] , & pp ) )
ret = ECMD_FAILED ;
2009-07-26 05:54:20 +04:00
unlock_vg ( cmd , VG_ORPHANS ) ;
2007-06-15 14:11:14 +04:00
if ( sigint_caught ( ) )
return ret ;
2001-10-12 14:32:06 +04:00
}
2001-10-01 19:29:39 +04:00
2003-10-22 02:06:07 +04:00
return ret ;
2001-10-01 19:29:39 +04:00
}