2002-12-12 23:55:49 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2009-02-09 12:45:49 +03:00
* Copyright ( C ) 2004 - 2009 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
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2002-12-12 23:55:49 +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
2002-12-12 23:55:49 +03:00
*/
# include "tools.h"
# include "report.h"
2013-09-18 04:09:15 +04:00
static int _process_each_devtype ( struct cmd_context * cmd , int argc , void * handle )
{
if ( argc )
log_warn ( " WARNING: devtypes currently ignores command line arguments. " ) ;
if ( ! report_devtypes ( handle ) )
return_ECMD_FAILED ;
return ECMD_PROCESSED ;
}
2010-07-09 19:34:40 +04:00
static int _vgs_single ( struct cmd_context * cmd __attribute__ ( ( unused ) ) ,
2006-05-10 01:23:51 +04:00
const char * vg_name , struct volume_group * vg ,
2009-07-01 21:00:50 +04:00
void * handle )
2002-12-12 23:55:49 +03:00
{
2015-01-20 15:16:41 +03:00
if ( ! report_object ( handle , vg , NULL , NULL , NULL , NULL , NULL , NULL ) )
2013-07-01 13:27:22 +04:00
return_ECMD_FAILED ;
2002-12-12 23:55:49 +03:00
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
}
2015-01-14 12:31:24 +03:00
static void _choose_lv_segment_for_status_report ( const struct logical_volume * lv , const struct lv_segment * * lv_seg )
2002-12-12 23:55:49 +03:00
{
2014-11-13 16:14:20 +03:00
/*
* By default , take the first LV segment to report status for .
* If there ' s any other specific segment that needs to be
* reported instead for the LV , choose it here and assign it
* to lvdm - > seg_status - > seg . This is the segment whose
* status line will be used for report exactly .
*/
* lv_seg = first_seg ( lv ) ;
}
2014-07-02 11:45:53 +04:00
2015-01-14 12:31:24 +03:00
static int _do_info_and_status ( struct cmd_context * cmd ,
const struct logical_volume * lv ,
const struct lv_segment * lv_seg ,
struct lv_with_info_and_seg_status * status ,
int do_info , int do_status )
2014-11-13 16:14:20 +03:00
{
2015-01-20 14:38:38 +03:00
unsigned use_layer = lv_is_thin_pool ( lv ) ? 1 : 0 ;
2014-11-13 16:14:20 +03:00
2015-01-20 14:38:38 +03:00
status - > lv = lv ;
2015-01-14 12:31:24 +03:00
if ( do_status ) {
if ( ! ( status - > seg_status . mem = dm_pool_create ( " reporter_pool " , 1024 ) ) )
return_0 ;
2014-11-13 16:14:20 +03:00
if ( ! lv_seg )
_choose_lv_segment_for_status_report ( lv , & lv_seg ) ;
2015-01-30 17:29:39 +03:00
if ( do_info ) {
2015-01-14 12:31:24 +03:00
/* both info and status */
2015-01-20 14:38:38 +03:00
status - > info_ok = lv_info_with_seg_status ( cmd , lv , lv_seg , use_layer , status , 1 , 1 ) ;
2015-01-30 17:29:39 +03:00
/* for inactive thin-pools reset lv info struct */
if ( use_layer & & status - > info_ok & &
! lv_info ( cmd , lv , 0 , NULL , 0 , 0 ) )
memset ( & status - > info , 0 , sizeof ( status - > info ) ) ;
} else
2015-01-14 12:31:24 +03:00
/* status only */
2015-01-20 14:38:38 +03:00
status - > info_ok = lv_status ( cmd , lv_seg , use_layer , & status - > seg_status ) ;
} else if ( do_info )
2015-01-14 12:31:24 +03:00
/* info only */
2015-01-20 14:38:38 +03:00
status - > info_ok = lv_info ( cmd , lv , use_layer , & status - > info , 1 , 1 ) ;
2015-01-14 12:31:24 +03:00
return 1 ;
2014-07-02 11:45:53 +04:00
}
2014-11-13 16:14:20 +03:00
static int _do_lvs_with_info_and_status_single ( struct cmd_context * cmd ,
2015-01-14 12:31:24 +03:00
const struct logical_volume * lv ,
2014-11-13 16:14:20 +03:00
int do_info , int do_status ,
void * handle )
2014-07-11 12:18:59 +04:00
{
2015-01-20 15:16:41 +03:00
struct lv_with_info_and_seg_status status = {
. seg_status . type = SEG_STATUS_NONE
} ;
2014-11-13 16:14:20 +03:00
int r = ECMD_FAILED ;
2015-01-14 12:31:24 +03:00
if ( ! _do_info_and_status ( cmd , lv , NULL , & status , do_info , do_status ) ) {
stack ;
return r ;
}
2014-11-13 16:14:20 +03:00
if ( ! report_object ( handle , lv - > vg , lv , NULL , NULL , NULL ,
2015-01-20 15:16:41 +03:00
& status , NULL ) )
2015-01-14 12:31:24 +03:00
goto_out ;
2014-11-13 16:14:20 +03:00
r = ECMD_PROCESSED ;
out :
2015-01-14 12:31:24 +03:00
if ( status . seg_status . mem )
dm_pool_destroy ( status . seg_status . mem ) ;
2014-11-13 16:14:20 +03:00
return r ;
2014-07-11 12:18:59 +04:00
}
2014-11-13 16:14:20 +03:00
static int _lvs_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
2014-10-21 14:01:57 +04:00
{
2014-11-13 16:14:20 +03:00
return _do_lvs_with_info_and_status_single ( cmd , lv , 0 , 0 , handle ) ;
2014-10-21 14:01:57 +04:00
}
2014-07-02 11:45:53 +04:00
static int _lvs_with_info_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
2014-11-13 16:14:20 +03:00
return _do_lvs_with_info_and_status_single ( cmd , lv , 1 , 0 , handle ) ;
}
2002-12-12 23:55:49 +03:00
2014-11-13 16:14:20 +03:00
static int _lvs_with_status_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
return _do_lvs_with_info_and_status_single ( cmd , lv , 0 , 1 , handle ) ;
2002-12-12 23:55:49 +03:00
}
2014-11-13 16:14:20 +03:00
static int _lvs_with_info_and_status_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
2014-10-21 14:01:57 +04:00
{
2014-11-13 16:14:20 +03:00
return _do_lvs_with_info_and_status_single ( cmd , lv , 1 , 1 , handle ) ;
2014-10-21 14:01:57 +04:00
}
2014-11-13 16:14:20 +03:00
static int _do_segs_with_info_and_status_single ( struct cmd_context * cmd ,
2015-01-14 12:31:24 +03:00
const struct lv_segment * seg ,
2014-11-13 16:14:20 +03:00
int do_info , int do_status ,
void * handle )
2014-10-21 14:01:57 +04:00
{
2015-01-20 15:16:41 +03:00
struct lv_with_info_and_seg_status status = {
. seg_status . type = SEG_STATUS_NONE
} ;
2014-10-21 14:01:57 +04:00
int r = ECMD_FAILED ;
2015-01-14 12:31:24 +03:00
if ( ! _do_info_and_status ( cmd , seg - > lv , seg , & status , do_info , do_status ) ) {
stack ;
return r ;
}
2014-11-13 16:14:20 +03:00
if ( ! report_object ( handle , seg - > lv - > vg , seg - > lv , NULL , seg , NULL ,
2015-01-20 15:16:41 +03:00
& status , NULL ) )
2015-01-14 12:31:24 +03:00
goto_out ;
2014-10-21 14:01:57 +04:00
r = ECMD_PROCESSED ;
out :
2015-01-14 12:31:24 +03:00
if ( status . seg_status . mem )
dm_pool_destroy ( status . seg_status . mem ) ;
2014-10-21 14:01:57 +04:00
return r ;
}
2014-11-13 16:14:20 +03:00
static int _segs_single ( struct cmd_context * cmd , struct lv_segment * seg ,
void * handle )
2002-12-12 23:55:49 +03:00
{
2014-11-13 16:14:20 +03:00
return _do_segs_with_info_and_status_single ( cmd , seg , 0 , 0 , handle ) ;
}
2002-12-12 23:55:49 +03:00
2014-11-13 16:14:20 +03:00
static int _segs_with_info_single ( struct cmd_context * cmd , struct lv_segment * seg ,
void * handle )
{
return _do_segs_with_info_and_status_single ( cmd , seg , 1 , 0 , handle ) ;
2002-12-12 23:55:49 +03:00
}
2014-07-07 17:54:13 +04:00
2014-11-13 16:14:20 +03:00
static int _segs_with_status_single ( struct cmd_context * cmd , struct lv_segment * seg ,
void * handle )
2014-07-07 17:54:13 +04:00
{
2014-11-13 16:14:20 +03:00
return _do_segs_with_info_and_status_single ( cmd , seg , 0 , 1 , handle ) ;
}
2014-07-07 17:54:13 +04:00
2014-11-13 16:14:20 +03:00
static int _segs_with_info_and_status_single ( struct cmd_context * cmd , struct lv_segment * seg ,
void * handle )
{
return _do_segs_with_info_and_status_single ( cmd , seg , 1 , 1 , handle ) ;
}
2014-07-07 17:54:13 +04:00
2014-11-13 16:14:20 +03:00
static int _lvsegs_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
return ECMD_PROCESSED ;
return process_each_segment_in_lv ( cmd , lv , handle , _segs_single ) ;
2014-07-07 17:54:13 +04:00
}
2014-11-13 16:14:20 +03:00
static int _lvsegs_with_info_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
2014-10-21 14:01:57 +04:00
{
2014-11-13 16:14:20 +03:00
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
return ECMD_PROCESSED ;
2014-10-21 14:01:57 +04:00
2014-11-13 16:14:20 +03:00
return process_each_segment_in_lv ( cmd , lv , handle , _segs_with_info_single ) ;
}
2014-10-21 14:01:57 +04:00
2014-11-13 16:14:20 +03:00
static int _lvsegs_with_status_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
return ECMD_PROCESSED ;
return process_each_segment_in_lv ( cmd , lv , handle , _segs_with_status_single ) ;
}
static int _lvsegs_with_info_and_status_single ( struct cmd_context * cmd , struct logical_volume * lv ,
void * handle )
{
if ( ! arg_count ( cmd , all_ARG ) & & ! lv_is_visible ( lv ) )
return ECMD_PROCESSED ;
return process_each_segment_in_lv ( cmd , lv , handle , _segs_with_info_and_status_single ) ;
2014-10-21 14:01:57 +04:00
}
2014-07-07 17:54:13 +04:00
static int _do_pvsegs_sub_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct pv_segment * pvseg ,
2014-11-13 16:14:20 +03:00
int do_info ,
int do_status ,
2014-07-07 17:54:13 +04:00
void * handle )
2005-04-20 00:58:25 +04:00
{
int ret = ECMD_PROCESSED ;
2007-12-15 00:53:02 +03:00
struct lv_segment * seg = pvseg - > lvseg ;
2014-10-22 16:30:33 +04:00
struct segment_type _freeseg_type = {
. name = " free " ,
. flags = SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED ,
} ;
2005-04-20 00:58:25 +04:00
2009-04-21 16:59:18 +04:00
struct volume_group _free_vg = {
. cmd = cmd ,
2011-02-18 17:47:28 +03:00
. name = " " ,
2014-10-22 16:30:33 +04:00
. pvs = DM_LIST_HEAD_INIT ( _free_vg . pvs ) ,
. lvs = DM_LIST_HEAD_INIT ( _free_vg . lvs ) ,
. tags = DM_LIST_HEAD_INIT ( _free_vg . tags ) ,
2009-04-21 16:59:18 +04:00
} ;
2008-06-25 20:52:27 +04:00
struct logical_volume _free_logical_volume = {
2009-04-21 16:59:18 +04:00
. vg = vg ? : & _free_vg ,
2011-02-18 17:47:28 +03:00
. name = " " ,
2008-06-25 20:52:27 +04:00
. status = VISIBLE_LV ,
. major = - 1 ,
. minor = - 1 ,
2014-10-22 16:30:33 +04:00
. tags = DM_LIST_HEAD_INIT ( _free_logical_volume . tags ) ,
. segments = DM_LIST_HEAD_INIT ( _free_logical_volume . segments ) ,
. segs_using_this_lv = DM_LIST_HEAD_INIT ( _free_logical_volume . segs_using_this_lv ) ,
. snapshot_segs = DM_LIST_HEAD_INIT ( _free_logical_volume . snapshot_segs ) ,
2008-06-25 20:52:27 +04:00
} ;
struct lv_segment _free_lv_segment = {
2010-03-16 18:30:48 +03:00
. lv = & _free_logical_volume ,
2014-10-22 16:30:33 +04:00
. segtype = & _freeseg_type ,
. len = pvseg - > len ,
. tags = DM_LIST_HEAD_INIT ( _free_lv_segment . tags ) ,
. origin_list = DM_LIST_HEAD_INIT ( _free_lv_segment . origin_list ) ,
2008-06-25 20:52:27 +04:00
} ;
2015-01-20 15:16:41 +03:00
struct lv_with_info_and_seg_status status = {
. seg_status . type = SEG_STATUS_NONE ,
. lv = & _free_logical_volume
} ;
2014-11-13 16:14:20 +03:00
if ( seg )
2015-01-14 12:31:24 +03:00
_do_info_and_status ( cmd , seg - > lv , seg , & status , do_info , do_status ) ;
2014-07-07 17:54:13 +04:00
2008-06-25 20:52:27 +04:00
if ( ! report_object ( handle , vg , seg ? seg - > lv : & _free_logical_volume , pvseg - > pv ,
2015-01-20 15:16:41 +03:00
seg ? : & _free_lv_segment , pvseg , & status ,
2014-10-20 15:46:50 +04:00
pv_label ( pvseg - > pv ) ) ) {
2006-09-02 05:18:17 +04:00
ret = ECMD_FAILED ;
2013-07-01 13:27:11 +04:00
goto_out ;
2009-09-15 02:47:49 +04:00
}
2011-03-09 15:44:42 +03:00
2010-11-18 01:26:42 +03:00
out :
2015-01-14 12:31:24 +03:00
if ( status . seg_status . mem )
dm_pool_destroy ( status . seg_status . mem ) ;
2005-04-20 00:58:25 +04:00
return ret ;
}
2014-07-07 17:54:13 +04:00
static int _pvsegs_sub_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
2014-11-13 16:14:20 +03:00
struct pv_segment * pvseg ,
void * handle )
2014-07-07 17:54:13 +04:00
{
2014-10-20 15:46:50 +04:00
return _do_pvsegs_sub_single ( cmd , vg , pvseg , 0 , 0 , handle ) ;
2014-07-07 17:54:13 +04:00
}
static int _pvsegs_with_lv_info_sub_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct pv_segment * pvseg ,
void * handle )
{
2014-10-20 15:46:50 +04:00
return _do_pvsegs_sub_single ( cmd , vg , pvseg , 1 , 0 , handle ) ;
2014-07-07 17:54:13 +04:00
}
2014-11-13 16:14:20 +03:00
static int _pvsegs_with_lv_status_sub_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct pv_segment * pvseg ,
void * handle )
2002-12-12 23:55:49 +03:00
{
2014-11-13 16:14:20 +03:00
return _do_pvsegs_sub_single ( cmd , vg , pvseg , 0 , 1 , handle ) ;
2002-12-12 23:55:49 +03:00
}
2014-11-13 16:14:20 +03:00
static int _pvsegs_with_lv_info_and_status_sub_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct pv_segment * pvseg ,
void * handle )
2014-07-07 17:54:13 +04:00
{
2014-11-13 16:14:20 +03:00
return _do_pvsegs_sub_single ( cmd , vg , pvseg , 1 , 1 , handle ) ;
2014-07-07 17:54:13 +04:00
}
2014-11-13 16:14:20 +03:00
static int _pvsegs_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct physical_volume * pv ,
void * handle )
2005-04-20 00:58:25 +04:00
{
2014-11-13 16:14:20 +03:00
return process_each_segment_in_pv ( cmd , vg , pv , handle , _pvsegs_sub_single ) ;
2005-04-20 00:58:25 +04:00
}
2014-07-07 17:54:13 +04:00
static int _pvsegs_with_lv_info_single ( struct cmd_context * cmd ,
struct volume_group * vg ,
struct physical_volume * pv ,
void * handle )
{
2014-11-13 16:14:20 +03:00
return process_each_segment_in_pv ( cmd , vg , pv , handle , _pvsegs_with_lv_info_sub_single ) ;
}
static int _pvsegs_with_lv_status_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_with_lv_status_sub_single ) ;
}
static int _pvsegs_with_lv_info_and_status_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_with_lv_info_and_status_sub_single ) ;
2014-07-07 17:54:13 +04:00
}
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 )
{
2015-01-20 15:16:41 +03:00
if ( ! report_object ( handle , vg , NULL , pv , NULL , NULL , NULL , NULL ) )
2014-10-07 03:34:04 +04:00
return_ECMD_FAILED ;
2009-04-10 14:01:38 +04:00
2014-10-07 03:34:04 +04:00
return ECMD_PROCESSED ;
2002-12-12 23:55:49 +03:00
}
2013-07-29 21:07:11 +04:00
static int _label_single ( struct cmd_context * cmd , struct label * label ,
void * handle )
2009-02-09 12:45:49 +03:00
{
2015-01-20 15:16:41 +03:00
if ( ! report_object ( handle , NULL , NULL , NULL , NULL , NULL , NULL , label ) )
2013-07-01 13:27:22 +04:00
return_ECMD_FAILED ;
2009-02-09 12:45:49 +03:00
return ECMD_PROCESSED ;
}
2007-01-27 05:09:06 +03:00
static int _pvs_in_vg ( struct cmd_context * cmd , const char * vg_name ,
2007-08-22 18:38:18 +04:00
struct volume_group * vg ,
2007-01-27 05:09:06 +03:00
void * handle )
{
2014-11-14 12:50:31 +03:00
int skip ;
2013-10-02 00:20:10 +04:00
2014-11-14 12:50:31 +03:00
if ( ignore_vg ( vg , vg_name , 0 , & skip ) )
return_ECMD_FAILED ;
if ( skip )
return ECMD_PROCESSED ;
2009-07-01 21:00:50 +04:00
2014-10-07 03:34:04 +04:00
return process_each_pv_in_vg ( cmd , vg , handle , & _pvs_single ) ;
2007-01-27 05:09:06 +03:00
}
2007-01-27 05:32:31 +03:00
static int _pvsegs_in_vg ( struct cmd_context * cmd , const char * vg_name ,
2007-08-22 18:38:18 +04:00
struct volume_group * vg ,
2007-01-27 05:32:31 +03:00
void * handle )
{
2014-11-14 12:50:31 +03:00
int skip ;
2013-10-02 00:20:10 +04:00
2014-11-14 12:50:31 +03:00
if ( ignore_vg ( vg , vg_name , 0 , & skip ) )
return_ECMD_FAILED ;
if ( skip )
return ECMD_PROCESSED ;
2009-07-01 21:00:50 +04:00
2014-10-07 03:34:04 +04:00
return process_each_pv_in_vg ( cmd , vg , handle , & _pvsegs_single ) ;
2007-01-27 05:32:31 +03:00
}
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 ;
2014-05-29 11:38:59 +04:00
const char * keys = NULL , * options = NULL , * selection = NULL , * separator ;
2003-10-22 02:06:07 +04:00
int r = ECMD_PROCESSED ;
2008-06-25 01:21:04 +04:00
int aligned , buffered , headings , field_prefixes , quoted ;
2008-06-25 02:48:53 +04:00
int columns_as_rows ;
2014-10-21 14:01:57 +04:00
unsigned args_are_pvs , lv_info_needed , lv_segment_status_needed ;
2014-10-07 03:34:04 +04:00
int lock_global = 0 ;
2002-12-12 23:55:49 +03:00
2013-06-25 14:31:53 +04:00
aligned = find_config_tree_bool ( cmd , report_aligned_CFG , NULL ) ;
buffered = find_config_tree_bool ( cmd , report_buffered_CFG , NULL ) ;
headings = find_config_tree_bool ( cmd , report_headings_CFG , NULL ) ;
2013-06-25 14:29:54 +04:00
separator = find_config_tree_str ( cmd , report_separator_CFG , NULL ) ;
2013-06-25 14:31:53 +04:00
field_prefixes = find_config_tree_bool ( cmd , report_prefixes_CFG , NULL ) ;
quoted = find_config_tree_bool ( cmd , report_quoted_CFG , NULL ) ;
columns_as_rows = find_config_tree_bool ( cmd , report_colums_as_rows_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
2009-02-09 12:45:49 +03:00
args_are_pvs = ( report_type = = PVS | |
report_type = = LABEL | |
report_type = = PVSEGS ) ? 1 : 0 ;
2007-01-27 05:09:06 +03:00
2014-04-04 04:41:06 +04:00
/*
* FIXME Trigger scans based on unrecognised listed devices instead .
*/
2014-04-01 16:46:22 +04:00
if ( args_are_pvs & & argc )
cmd - > filter - > wipe ( cmd - > filter ) ;
2002-12-12 23:55:49 +03:00
switch ( report_type ) {
2013-09-18 04:09:15 +04:00
case DEVTYPES :
keys = find_config_tree_str ( cmd , report_devtypes_sort_CFG , NULL ) ;
if ( ! arg_count ( cmd , verbose_ARG ) )
options = find_config_tree_str ( cmd , report_devtypes_cols_CFG , NULL ) ;
else
options = find_config_tree_str ( cmd , report_devtypes_cols_verbose_CFG , NULL ) ;
break ;
2002-12-12 23:55:49 +03:00
case LVS :
2013-06-25 14:29:54 +04:00
keys = find_config_tree_str ( cmd , report_lvs_sort_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
if ( ! arg_count ( cmd , verbose_ARG ) )
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_lvs_cols_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
else
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_lvs_cols_verbose_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
break ;
case VGS :
2013-06-25 14:29:54 +04:00
keys = find_config_tree_str ( cmd , report_vgs_sort_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
if ( ! arg_count ( cmd , verbose_ARG ) )
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_vgs_cols_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
else
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_vgs_cols_verbose_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
break ;
2009-02-09 12:45:49 +03:00
case LABEL :
2002-12-12 23:55:49 +03:00
case PVS :
2013-06-25 14:29:54 +04:00
keys = find_config_tree_str ( cmd , report_pvs_sort_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
if ( ! arg_count ( cmd , verbose_ARG ) )
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_pvs_cols_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
else
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_pvs_cols_verbose_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
break ;
case SEGS :
2013-06-25 14:29:54 +04:00
keys = find_config_tree_str ( cmd , report_segs_sort_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
if ( ! arg_count ( cmd , verbose_ARG ) )
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_segs_cols_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
else
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_segs_cols_verbose_CFG , NULL ) ;
2002-12-12 23:55:49 +03:00
break ;
2005-04-20 00:58:25 +04:00
case PVSEGS :
2013-06-25 14:29:54 +04:00
keys = find_config_tree_str ( cmd , report_pvsegs_sort_CFG , NULL ) ;
2005-04-20 00:58:25 +04:00
if ( ! arg_count ( cmd , verbose_ARG ) )
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_pvsegs_cols_CFG , NULL ) ;
2005-04-20 00:58:25 +04:00
else
2013-06-25 14:29:54 +04:00
options = find_config_tree_str ( cmd , report_pvsegs_cols_verbose_CFG , NULL ) ;
2005-04-20 00:58:25 +04:00
break ;
2012-02-13 15:25:56 +04:00
default :
log_error ( INTERNAL_ERROR " Unknown report type. " ) ;
return ECMD_FAILED ;
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 ) ;
2008-01-20 04:23:46 +03:00
return EINVALID_CMD_LINE ;
2002-12-12 23:55:49 +03:00
}
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 " ) ;
2008-01-20 04:23:46 +03:00
return ECMD_FAILED ;
2006-05-10 21:49:25 +04:00
}
2013-04-29 14:33:38 +04:00
( void ) sprintf ( str , " %s,%s " , options , opts + 1 ) ;
2002-12-12 23:55:49 +03:00
options = str ;
} else
options = opts ;
}
/* -O overrides default sort settings */
2009-11-03 18:50:42 +03:00
keys = arg_str_value ( cmd , sort_ARG , keys ) ;
2002-12-12 23:55:49 +03:00
2009-11-03 18:50:42 +03:00
separator = arg_str_value ( cmd , separator_ARG , separator ) ;
2002-12-12 23:55:49 +03:00
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 ;
2008-06-06 23:28:35 +04:00
if ( arg_count ( cmd , nameprefixes_ARG ) ) {
2008-04-20 04:15:08 +04:00
aligned = 0 ;
field_prefixes = 1 ;
}
2008-06-25 01:21:04 +04:00
if ( arg_count ( cmd , unquoted_ARG ) )
quoted = 0 ;
2008-06-25 02:48:53 +04:00
if ( arg_count ( cmd , rows_ARG ) )
columns_as_rows = 1 ;
2002-12-12 23:55:49 +03:00
2014-05-29 11:38:59 +04:00
if ( arg_count ( cmd , select_ARG ) )
selection = arg_str_value ( cmd , select_ARG , NULL ) ;
2002-12-12 23:55:49 +03:00
if ( ! ( report_handle = report_init ( cmd , options , keys , & report_type ,
separator , aligned , buffered ,
2008-06-25 02:48:53 +04:00
headings , field_prefixes , quoted ,
2014-06-19 17:33:16 +04:00
columns_as_rows , selection ) ) )
2013-07-01 13:27:22 +04:00
return_ECMD_FAILED ;
2002-12-12 23:55:49 +03:00
2014-10-21 14:01:57 +04:00
/* Do we need to acquire LV device info in addition? */
2015-01-20 18:02:48 +03:00
lv_info_needed = ( report_type & ( LVSINFO | LVSINFOSTATUS ) ) ? 1 : 0 ;
2014-07-07 17:54:13 +04:00
2014-10-21 14:01:57 +04:00
/* Do we need to acquire LV device status in addition? */
2015-01-20 18:02:48 +03:00
lv_segment_status_needed = ( report_type & ( SEGSSTATUS | LVSSTATUS | LVSINFOSTATUS ) ) ? 1 : 0 ;
2014-10-21 14:01:57 +04:00
2007-01-16 21:06:12 +03:00
/* Ensure options selected are compatible */
2014-10-21 14:01:57 +04:00
if ( report_type & ( SEGS | SEGSSTATUS ) )
2007-01-16 21:06:12 +03:00
report_type | = LVS ;
if ( report_type & PVSEGS )
report_type | = PVS ;
2015-01-20 18:02:48 +03:00
if ( ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) ) & & ( report_type & ( PVS | LABEL ) ) & & ! args_are_pvs ) {
2007-01-16 21:06:12 +03:00
log_error ( " Can't report LV and PV fields at the same time " ) ;
2007-02-14 18:18:31 +03:00
dm_report_free ( report_handle ) ;
2008-01-20 04:23:46 +03:00
return ECMD_FAILED ;
2007-01-16 21:06:12 +03:00
}
/* Change report type if fields specified makes this necessary */
2007-12-15 00:53:02 +03:00
if ( ( report_type & PVSEGS ) | |
2015-01-20 18:02:48 +03:00
( ( report_type & ( PVS | LABEL ) ) & & ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) ) ) )
2007-01-16 21:06:12 +03:00
report_type = PVSEGS ;
2009-02-09 12:45:49 +03:00
else if ( ( report_type & LABEL ) & & ( report_type & VGS ) )
report_type = PVS ;
2007-01-16 21:06:12 +03:00
else if ( report_type & PVS )
report_type = PVS ;
2014-10-21 14:01:57 +04:00
else if ( report_type & ( SEGS | SEGSSTATUS ) )
2007-12-15 00:53:02 +03:00
report_type = SEGS ;
2015-01-20 18:02:48 +03:00
else if ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) )
2007-12-15 00:53:02 +03:00
report_type = LVS ;
2007-01-16 21:06:12 +03:00
2014-10-07 03:34:04 +04:00
/*
* We lock VG_GLOBAL to enable use of metadata cache .
* This can pause alongide pvscan or vgscan process for a while .
*/
if ( args_are_pvs & & ( report_type = = PVS | | report_type = = PVSEGS ) & &
! lvmetad_active ( ) ) {
lock_global = 1 ;
if ( ! lock_vol ( cmd , VG_GLOBAL , LCK_VG_READ , NULL ) ) {
log_error ( " Unable to obtain global lock. " ) ;
2014-11-13 19:39:22 +03:00
dm_report_free ( report_handle ) ;
2014-10-07 03:34:04 +04:00
return ECMD_FAILED ;
}
}
2002-12-12 23:55:49 +03:00
switch ( report_type ) {
2013-09-18 04:09:15 +04:00
case DEVTYPES :
r = _process_each_devtype ( cmd , argc , report_handle ) ;
break ;
2014-11-05 12:46:52 +03:00
case LVSINFO :
/* fall through */
2014-10-21 14:01:57 +04:00
case LVSSTATUS :
/* fall through */
2015-01-20 18:02:48 +03:00
case LVSINFOSTATUS :
/* fall through */
2002-12-12 23:55:49 +03:00
case LVS :
2009-07-01 21:00:50 +04:00
r = process_each_lv ( cmd , argc , argv , 0 , report_handle ,
2014-11-13 16:14:20 +03:00
lv_info_needed & & ! lv_segment_status_needed ? & _lvs_with_info_single :
! lv_info_needed & & lv_segment_status_needed ? & _lvs_with_status_single :
lv_info_needed & & lv_segment_status_needed ? & _lvs_with_info_and_status_single :
& _lvs_single ) ;
2014-07-02 11:45:53 +04:00
break ;
2002-12-12 23:55:49 +03:00
case VGS :
2009-07-01 21:00:50 +04:00
r = process_each_vg ( cmd , argc , argv , 0 ,
2003-10-22 02:06:07 +04:00
report_handle , & _vgs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
2009-02-09 12:45:49 +03:00
case LABEL :
2013-07-29 21:14:51 +04:00
r = process_each_label ( cmd , argc , argv ,
report_handle , & _label_single ) ;
2009-02-09 12:45:49 +03:00
break ;
2002-12-12 23:55:49 +03:00
case PVS :
2007-01-27 05:09:06 +03:00
if ( args_are_pvs )
2009-07-15 09:50:22 +04:00
r = process_each_pv ( cmd , argc , argv , NULL , 0 ,
2014-10-07 03:34:04 +04:00
report_handle , & _pvs_single ) ;
2007-01-27 05:09:06 +03:00
else
2009-07-01 21:00:50 +04:00
r = process_each_vg ( cmd , argc , argv , 0 ,
2007-01-27 05:09:06 +03:00
report_handle , & _pvs_in_vg ) ;
2002-12-12 23:55:49 +03:00
break ;
2014-10-21 14:01:57 +04:00
case SEGSSTATUS :
/* fall through */
2002-12-12 23:55:49 +03:00
case SEGS :
2009-07-01 21:00:50 +04:00
r = process_each_lv ( cmd , argc , argv , 0 , report_handle ,
2014-11-13 16:14:20 +03:00
lv_info_needed & & ! lv_segment_status_needed ? & _lvsegs_with_info_single :
! lv_info_needed & & lv_segment_status_needed ? & _lvsegs_with_status_single :
lv_info_needed & & lv_segment_status_needed ? & _lvsegs_with_info_and_status_single :
& _lvsegs_single ) ;
2002-12-12 23:55:49 +03:00
break ;
2005-04-20 00:58:25 +04:00
case PVSEGS :
2007-01-27 05:09:06 +03:00
if ( args_are_pvs )
2009-07-15 09:50:22 +04:00
r = process_each_pv ( cmd , argc , argv , NULL , 0 ,
2014-10-07 03:34:04 +04:00
report_handle ,
2014-11-13 16:14:20 +03:00
lv_info_needed & & ! lv_segment_status_needed ? & _pvsegs_with_lv_info_single :
! lv_info_needed & & lv_segment_status_needed ? & _pvsegs_with_lv_status_single :
lv_info_needed & & lv_segment_status_needed ? & _pvsegs_with_lv_info_and_status_single :
& _pvsegs_single ) ;
2007-01-27 05:09:06 +03:00
else
2009-07-01 21:00:50 +04:00
r = process_each_vg ( cmd , argc , argv , 0 ,
2007-01-27 05:32:31 +03:00
report_handle , & _pvsegs_in_vg ) ;
2005-04-20 00:58:25 +04:00
break ;
2002-12-12 23:55:49 +03:00
}
2014-12-05 13:46:26 +03:00
if ( find_config_tree_bool ( cmd , report_compact_output_CFG , NULL ) & &
! dm_report_compact_fields ( report_handle ) )
log_error ( " Failed to compact report output. " ) ;
2007-01-16 21:06:12 +03:00
dm_report_output ( report_handle ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
dm_report_free ( report_handle ) ;
2014-10-07 03:34:04 +04:00
if ( lock_global )
unlock_vg ( cmd , VG_GLOBAL ) ;
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
2009-02-09 12:45:49 +03:00
type = LABEL ;
2005-04-20 00:58:25 +04:00
return _report ( cmd , argc , argv , type ) ;
2002-12-12 23:55:49 +03:00
}
2013-09-18 04:09:15 +04:00
int devtypes ( struct cmd_context * cmd , int argc , char * * argv )
{
return _report ( cmd , argc , argv , DEVTYPES ) ;
}