2002-12-12 23:55:49 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 Red Hat , Inc . All rights reserved .
2002-12-12 23:55:49 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2002-12-12 23:55:49 +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
* of the GNU General Public License v .2 .
2002-12-12 23:55:49 +03:00
*
* You should have received a copy of the GNU 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
2002-12-12 23:55:49 +03:00
*/
# include "tools.h"
# include "report.h"
2006-05-10 01:23:51 +04:00
static int _vgs_single ( struct cmd_context * cmd __attribute ( ( unused ) ) ,
const char * vg_name , struct volume_group * vg ,
int consistent __attribute ( ( unused ) ) , void * handle )
2002-12-12 23:55:49 +03:00
{
if ( ! vg ) {
log_error ( " Volume group %s not found " , vg_name ) ;
return ECMD_FAILED ;
}
2005-04-20 00:58:25 +04:00
if ( ! report_object ( handle , vg , NULL , NULL , NULL , NULL ) )
2002-12-12 23:55:49 +03:00
return ECMD_FAILED ;
2005-05-17 17:44:02 +04:00
check_current_backup ( vg ) ;
2003-10-22 02:06:07 +04:00
return ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
}
static int _lvs_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
2006-04-07 21:41:56 +04:00
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
2005-06-03 18:49:51 +04:00
return ECMD_PROCESSED ;
2005-04-20 00:58:25 +04:00
if ( ! report_object ( handle , lv - > vg , lv , NULL , NULL , NULL ) )
2002-12-12 23:55:49 +03:00
return ECMD_FAILED ;
2003-10-22 02:06:07 +04:00
return ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
}
2006-05-10 01:23:51 +04:00
static int _segs_single ( struct cmd_context * cmd __attribute ( ( unused ) ) ,
struct lv_segment * seg , void * handle )
2002-12-12 23:55:49 +03:00
{
2005-04-20 00:58:25 +04:00
if ( ! report_object ( handle , seg - > lv - > vg , seg - > lv , NULL , seg , NULL ) )
2002-12-12 23:55:49 +03:00
return ECMD_FAILED ;
2003-10-22 02:06:07 +04:00
return ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
}
2005-04-20 00:58:25 +04:00
static int _pvsegs_sub_single ( struct cmd_context * cmd , struct volume_group * vg ,
struct pv_segment * pvseg , void * handle )
{
int consistent = 0 ;
struct physical_volume * pv = pvseg - > pv ;
int ret = ECMD_PROCESSED ;
if ( ! lock_vol ( cmd , pv - > vg_name , LCK_VG_READ ) ) {
log_error ( " Can't lock %s: skipping " , pv - > vg_name ) ;
return ECMD_FAILED ;
}
2006-04-13 01:23:04 +04:00
if ( ! ( vg = vg_read ( cmd , pv - > vg_name , NULL , & consistent ) ) ) {
2005-04-20 00:58:25 +04:00
log_error ( " Can't read %s: skipping " , pv - > vg_name ) ;
unlock_vg ( cmd , pv - > vg_name ) ;
return ECMD_FAILED ;
}
if ( ! report_object ( handle , vg , NULL , pv , NULL , pvseg ) )
ret = ECMD_FAILED ;
unlock_vg ( cmd , pv - > vg_name ) ;
return ret ;
}
2002-12-12 23:55:49 +03:00
static int _lvsegs_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
2006-04-07 21:41:56 +04:00
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
2005-06-03 18:49:51 +04:00
return ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
return process_each_segment_in_lv ( cmd , lv , handle , _segs_single ) ;
}
2005-04-20 00:58:25 +04:00
static int _pvsegs_single ( struct cmd_context * cmd , struct volume_group * vg ,
struct physical_volume * pv , void * handle )
{
return process_each_segment_in_pv ( cmd , vg , pv , handle ,
_pvsegs_sub_single ) ;
}
2002-12-12 23:55:49 +03:00
static int _pvs_single ( struct cmd_context * cmd , struct volume_group * vg ,
struct physical_volume * pv , void * handle )
{
int consistent = 0 ;
2004-05-24 18:14:10 +04:00
int ret = ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
2004-06-19 23:27:00 +04:00
if ( pv - > vg_name ) {
if ( ! lock_vol ( cmd , pv - > vg_name , LCK_VG_READ ) ) {
log_error ( " Can't lock %s: skipping " , pv - > vg_name ) ;
return ECMD_FAILED ;
}
2004-05-24 18:14:10 +04:00
2006-04-13 01:23:04 +04:00
if ( ! ( vg = vg_read ( cmd , pv - > vg_name , ( char * ) & pv - > vgid , & consistent ) ) ) {
2004-06-19 23:27:00 +04:00
log_error ( " Can't read %s: skipping " , pv - > vg_name ) ;
unlock_vg ( cmd , pv - > vg_name ) ;
return ECMD_FAILED ;
}
2003-03-24 21:22:48 +03:00
}
2002-12-12 23:55:49 +03:00
2005-04-20 00:58:25 +04:00
if ( ! report_object ( handle , vg , NULL , pv , NULL , NULL ) )
2004-05-24 18:14:10 +04:00
ret = ECMD_FAILED ;
2002-12-12 23:55:49 +03:00
2004-06-19 23:27:00 +04:00
if ( pv - > vg_name )
unlock_vg ( cmd , pv - > vg_name ) ;
2004-05-24 18:14:10 +04:00
return ret ;
2002-12-12 23:55:49 +03:00
}
static int _report ( struct cmd_context * cmd , int argc , char * * argv ,
report_type_t report_type )
{
void * report_handle ;
2002-12-20 02:25:55 +03:00
const char * opts ;
char * str ;
const char * keys = NULL , * options = NULL , * separator ;
2003-10-22 02:06:07 +04:00
int r = ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
int aligned , buffered , headings ;
2006-05-16 20:48:31 +04:00
aligned = find_config_tree_int ( cmd , " report/aligned " ,
2002-12-12 23:55:49 +03:00
DEFAULT_REP_ALIGNED ) ;
2006-05-16 20:48:31 +04:00
buffered = find_config_tree_int ( cmd , " report/buffered " ,
2002-12-12 23:55:49 +03:00
DEFAULT_REP_BUFFERED ) ;
2006-05-16 20:48:31 +04:00
headings = find_config_tree_int ( cmd , " report/headings " ,
2002-12-12 23:55:49 +03:00
DEFAULT_REP_HEADINGS ) ;
2006-05-16 20:48:31 +04:00
separator = find_config_tree_str ( cmd , " report/separator " ,
2002-12-12 23:55:49 +03:00
DEFAULT_REP_SEPARATOR ) ;
switch ( report_type ) {
case LVS :
2006-05-16 20:48:31 +04:00
keys = find_config_tree_str ( cmd , " report/lvs_sort " ,
2002-12-12 23:55:49 +03:00
DEFAULT_LVS_SORT ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2004-03-08 21:28:45 +03:00
" report/lvs_cols " ,
2002-12-12 23:55:49 +03:00
DEFAULT_LVS_COLS ) ;
else
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2002-12-12 23:55:49 +03:00
" report/lvs_cols_verbose " ,
2004-03-08 21:28:45 +03:00
DEFAULT_LVS_COLS_VERB ) ;
2002-12-12 23:55:49 +03:00
break ;
case VGS :
2006-05-16 20:48:31 +04:00
keys = find_config_tree_str ( cmd , " report/vgs_sort " ,
2002-12-12 23:55:49 +03:00
DEFAULT_VGS_SORT ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2004-03-08 21:28:45 +03:00
" report/vgs_cols " ,
2002-12-12 23:55:49 +03:00
DEFAULT_VGS_COLS ) ;
else
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2002-12-12 23:55:49 +03:00
" report/vgs_cols_verbose " ,
2004-03-08 21:28:45 +03:00
DEFAULT_VGS_COLS_VERB ) ;
2002-12-12 23:55:49 +03:00
break ;
case PVS :
2006-05-16 20:48:31 +04:00
keys = find_config_tree_str ( cmd , " report/pvs_sort " ,
2002-12-12 23:55:49 +03:00
DEFAULT_PVS_SORT ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2004-03-08 21:28:45 +03:00
" report/pvs_cols " ,
2002-12-12 23:55:49 +03:00
DEFAULT_PVS_COLS ) ;
else
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2002-12-12 23:55:49 +03:00
" report/pvs_cols_verbose " ,
2004-03-08 21:28:45 +03:00
DEFAULT_PVS_COLS_VERB ) ;
2002-12-12 23:55:49 +03:00
break ;
case SEGS :
2006-05-16 20:48:31 +04:00
keys = find_config_tree_str ( cmd , " report/segs_sort " ,
2002-12-12 23:55:49 +03:00
DEFAULT_SEGS_SORT ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2004-03-08 21:28:45 +03:00
" report/segs_cols " ,
2002-12-12 23:55:49 +03:00
DEFAULT_SEGS_COLS ) ;
else
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2002-12-12 23:55:49 +03:00
" report/segs_cols_verbose " ,
2004-03-08 21:28:45 +03:00
DEFAULT_SEGS_COLS_VERB ) ;
2002-12-12 23:55:49 +03:00
break ;
2005-04-20 00:58:25 +04:00
case PVSEGS :
2006-05-16 20:48:31 +04:00
keys = find_config_tree_str ( cmd , " report/pvsegs_sort " ,
2005-04-20 00:58:25 +04:00
DEFAULT_PVSEGS_SORT ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2005-04-20 00:58:25 +04:00
" report/pvsegs_cols " ,
DEFAULT_PVSEGS_COLS ) ;
else
2006-05-16 20:48:31 +04:00
options = find_config_tree_str ( cmd ,
2005-04-20 00:58:25 +04:00
" report/pvsegs_cols_verbose " ,
DEFAULT_PVSEGS_COLS_VERB ) ;
break ;
2002-12-12 23:55:49 +03:00
}
/* If -o supplied use it, else use default for report_type */
if ( arg_count ( cmd , options_ARG ) ) {
opts = arg_str_value ( cmd , options_ARG , " " ) ;
if ( ! opts | | ! * opts ) {
log_error ( " Invalid options string: %s " , opts ) ;
return 0 ;
}
if ( * opts = = ' + ' ) {
2006-05-10 21:49:25 +04:00
if ( ! ( str = dm_pool_alloc ( cmd - > mem ,
strlen ( options ) + strlen ( opts ) + 1 ) ) ) {
log_error ( " options string allocation failed " ) ;
return 0 ;
}
2002-12-12 23:55:49 +03:00
strcpy ( str , options ) ;
2002-12-20 02:25:55 +03:00
strcat ( str , " , " ) ;
strcat ( str , opts + 1 ) ;
2002-12-12 23:55:49 +03:00
options = str ;
} else
options = opts ;
}
/* -O overrides default sort settings */
if ( arg_count ( cmd , sort_ARG ) )
keys = arg_str_value ( cmd , sort_ARG , " " ) ;
if ( arg_count ( cmd , separator_ARG ) )
separator = arg_str_value ( cmd , separator_ARG , " " ) ;
if ( arg_count ( cmd , separator_ARG ) )
aligned = 0 ;
if ( arg_count ( cmd , aligned_ARG ) )
aligned = 1 ;
if ( arg_count ( cmd , unbuffered_ARG ) & & ! arg_count ( cmd , sort_ARG ) )
buffered = 0 ;
if ( arg_count ( cmd , noheadings_ARG ) )
headings = 0 ;
if ( ! ( report_handle = report_init ( cmd , options , keys , & report_type ,
separator , aligned , buffered ,
headings ) ) )
return 0 ;
switch ( report_type ) {
case LVS :
2003-10-22 02:06:07 +04:00
r = process_each_lv ( cmd , argc , argv , LCK_VG_READ , report_handle ,
& _lvs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
case VGS :
2003-10-22 02:06:07 +04:00
r = process_each_vg ( cmd , argc , argv , LCK_VG_READ , 0 ,
report_handle , & _vgs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
case PVS :
2003-10-22 02:06:07 +04:00
r = process_each_pv ( cmd , argc , argv , NULL , report_handle ,
& _pvs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
case SEGS :
2003-10-22 02:06:07 +04:00
r = process_each_lv ( cmd , argc , argv , LCK_VG_READ , report_handle ,
& _lvsegs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
2005-04-20 00:58:25 +04:00
case PVSEGS :
r = process_each_pv ( cmd , argc , argv , NULL , report_handle ,
& _pvsegs_single ) ;
break ;
2002-12-12 23:55:49 +03:00
}
report_output ( report_handle ) ;
report_free ( report_handle ) ;
2003-10-22 02:06:07 +04:00
return r ;
2002-12-12 23:55:49 +03:00
}
int lvs ( struct cmd_context * cmd , int argc , char * * argv )
{
report_type_t type ;
if ( arg_count ( cmd , segments_ARG ) )
type = SEGS ;
else
type = LVS ;
return _report ( cmd , argc , argv , type ) ;
}
int vgs ( struct cmd_context * cmd , int argc , char * * argv )
{
return _report ( cmd , argc , argv , VGS ) ;
}
int pvs ( struct cmd_context * cmd , int argc , char * * argv )
{
2005-04-20 00:58:25 +04:00
report_type_t type ;
if ( arg_count ( cmd , segments_ARG ) )
type = PVSEGS ;
else
type = PVS ;
return _report ( cmd , argc , argv , type ) ;
2002-12-12 23:55:49 +03:00
}