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"
2015-07-06 19:30:18 +03:00
2002-12-12 23:55:49 +03:00
# include "report.h"
2014-11-27 17:02:13 +03:00
static int _process_each_devtype ( struct cmd_context * cmd , int argc ,
struct processing_handle * handle )
2013-09-18 04:09:15 +04:00
{
if ( argc )
log_warn ( " WARNING: devtypes currently ignores command line arguments. " ) ;
2014-11-27 17:02:13 +03:00
if ( ! report_devtypes ( handle - > custom_handle ) )
2013-09-18 04:09:15 +04:00
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2002-12-12 23:55:49 +03:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_handle ;
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-07-11 12:18:59 +04:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_handle ;
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-02-09 13:48:21 +03:00
if ( ! _do_info_and_status ( cmd , lv , NULL , & status , do_info , do_status ) )
goto_out ;
2015-01-14 12:31:24 +03:00
2014-12-02 15:14:12 +03:00
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
lv - > vg , lv , NULL , NULL , NULL , & status , NULL ) )
2014-11-27 17:02:13 +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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-07-02 11:45:53 +04:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-10-21 14:01:57 +04:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_handle ;
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-02-09 13:48:21 +03:00
if ( ! _do_info_and_status ( cmd , seg - > lv , seg , & status , do_info , do_status ) )
goto_out ;
2015-01-14 12:31:24 +03:00
2014-12-02 15:14:12 +03:00
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
seg - > lv - > vg , seg - > lv , NULL , seg , NULL , & status , NULL ) )
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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-11-27 17:02:13 +03:00
struct processing_handle * handle )
2005-04-20 00:58:25 +04:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_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
} ;
2015-02-09 13:48:21 +03:00
if ( seg & & ! _do_info_and_status ( cmd , seg - > lv , seg , & status , do_info , do_status ) )
goto_out ;
2014-07-07 17:54:13 +04:00
2014-12-02 15:14:12 +03:00
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
vg , seg ? seg - > lv : & _free_logical_volume ,
pvseg - > pv , seg ? : & _free_lv_segment , pvseg ,
& status , 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 , 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * 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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-07-07 17:54:13 +04:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2014-11-13 16:14:20 +03:00
{
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 ,
2014-11-27 17:02:13 +03:00
struct physical_volume * pv ,
struct processing_handle * handle )
2002-12-12 23:55:49 +03:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_handle ;
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2009-02-09 12:45:49 +03:00
{
2014-12-02 15:14:12 +03:00
struct selection_handle * sh = handle - > selection_handle ;
if ( ! report_object ( sh ? : handle - > custom_handle , sh ! = NULL ,
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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2007-01-27 05:09:06 +03: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 ,
2014-11-27 17:02:13 +03:00
struct processing_handle * handle )
2007-01-27 05:32:31 +03: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
}
2014-12-01 16:04:29 +03:00
static int _get_final_report_type ( int args_are_pvs ,
report_type_t report_type ,
int * lv_info_needed ,
int * lv_segment_status_needed ,
report_type_t * final_report_type )
{
/* Do we need to acquire LV device info in addition? */
* lv_info_needed = ( report_type & ( LVSINFO | LVSINFOSTATUS ) ) ? 1 : 0 ;
/* Do we need to acquire LV device status in addition? */
* lv_segment_status_needed = ( report_type & ( SEGSSTATUS | LVSSTATUS | LVSINFOSTATUS ) ) ? 1 : 0 ;
/* Ensure options selected are compatible */
if ( report_type & ( SEGS | SEGSSTATUS ) )
report_type | = LVS ;
if ( report_type & PVSEGS )
report_type | = PVS ;
if ( ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) ) & &
( report_type & ( PVS | LABEL ) ) & & ! args_are_pvs ) {
log_error ( " Can't report LV and PV fields at the same time " ) ;
return 0 ;
}
/* Change report type if fields specified makes this necessary */
if ( ( report_type & PVSEGS ) | |
( ( report_type & ( PVS | LABEL ) ) & & ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) ) ) )
report_type = PVSEGS ;
else if ( ( report_type & PVS ) | |
( ( report_type & LABEL ) & & ( report_type & VGS ) ) )
report_type = PVS ;
else if ( report_type & ( SEGS | SEGSSTATUS ) )
report_type = SEGS ;
else if ( report_type & ( LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS ) )
report_type = LVS ;
* final_report_type = report_type ;
return 1 ;
}
2015-02-13 12:36:06 +03:00
int report_for_selection ( struct cmd_context * cmd ,
struct selection_handle * sh ,
2014-12-01 16:19:30 +03:00
struct physical_volume * pv ,
struct volume_group * vg ,
struct logical_volume * lv )
{
2014-12-01 17:40:03 +03:00
static const char * incorrect_report_type_msg = " report_for_selection: incorrect report type " ;
int args_are_pvs = sh - > orig_report_type = = PVS ;
int do_lv_info , do_lv_seg_status ;
2015-02-13 12:36:06 +03:00
struct processing_handle * handle ;
2014-12-01 17:40:03 +03:00
int r = 0 ;
if ( ! _get_final_report_type ( args_are_pvs ,
sh - > orig_report_type | sh - > report_type ,
& do_lv_info ,
& do_lv_seg_status ,
& sh - > report_type ) )
return_0 ;
2015-02-13 12:36:06 +03:00
if ( ! ( handle = init_processing_handle ( cmd ) ) )
return_0 ;
/*
* We ' re already reporting for select so override
* internal_report_for_select to 0 as we can call
* process_each_ * functions again and we could
* end up in an infinite loop if we didn ' t stop
* internal reporting for select right here .
*
* So the overall call trace from top to bottom looks like this :
*
* process_each_ * ( top - level one , using processing_handle with internal reporting enabled and selection_handle ) - >
* select_match_ * ( processing_handle with selection_handle ) - >
* report for selection - >
* ( creating new processing_handle here with internal reporting disabled ! ! ! )
* reporting_fn OR process_each_ * ( using * new * processing_handle with original selection_handle )
*
* The selection_handle is still reused so we can track
* whether any of the items the top - level one is composed
* of are still selected or not unerneath . Do not destroy
* this selection handle - it needs to be passed to upper
* layers to check the overall selection status .
*/
handle - > internal_report_for_select = 0 ;
handle - > selection_handle = sh ;
2014-12-01 17:40:03 +03:00
/*
* Remember :
2015-02-13 12:36:06 +03:00
* sh - > orig_report_type is the original report type requested ( what are we selecting ? PV / VG / LV ? )
* sh - > report_type is the report type actually used ( it counts with all types of fields used in selection criteria )
2014-12-01 17:40:03 +03:00
*/
switch ( sh - > orig_report_type ) {
case LVS :
switch ( sh - > report_type ) {
case LVS :
2015-02-13 12:36:06 +03:00
r = _do_lvs_with_info_and_status_single ( vg - > cmd , lv , do_lv_info , do_lv_seg_status , handle ) ;
2014-12-01 17:40:03 +03:00
break ;
case SEGS :
2015-02-13 12:36:06 +03:00
r = process_each_segment_in_lv ( vg - > cmd , lv , handle ,
2014-12-01 17:40:03 +03:00
do_lv_info & & ! do_lv_seg_status ? & _segs_with_info_single :
! do_lv_info & & do_lv_seg_status ? & _segs_with_status_single :
do_lv_info & & do_lv_seg_status ? & _segs_with_info_and_status_single :
& _segs_single ) ;
break ;
default :
log_error ( INTERNAL_ERROR " %s for LVS " , incorrect_report_type_msg ) ;
break ;
}
break ;
case VGS :
switch ( sh - > report_type ) {
case VGS :
2015-02-13 12:36:06 +03:00
r = _vgs_single ( vg - > cmd , vg - > name , vg , handle ) ;
2014-12-01 17:40:03 +03:00
break ;
case LVS :
2015-02-13 12:36:06 +03:00
r = process_each_lv_in_vg ( vg - > cmd , vg , NULL , NULL , 0 , handle ,
2014-12-01 17:40:03 +03:00
do_lv_info & & ! do_lv_seg_status ? & _lvs_with_info_single :
! do_lv_info & & do_lv_seg_status ? & _lvs_with_status_single :
do_lv_info & & do_lv_seg_status ? & _lvs_with_info_and_status_single :
& _lvs_single ) ;
break ;
case SEGS :
2015-02-13 12:36:06 +03:00
r = process_each_lv_in_vg ( vg - > cmd , vg , NULL , NULL , 0 , handle ,
2014-12-01 17:40:03 +03:00
do_lv_info & & ! do_lv_seg_status ? & _lvsegs_with_info_single :
! do_lv_info & & do_lv_seg_status ? & _lvsegs_with_status_single :
do_lv_info & & do_lv_seg_status ? & _lvsegs_with_info_and_status_single :
& _lvsegs_single ) ;
break ;
case PVS :
2015-02-13 12:36:06 +03:00
r = process_each_pv_in_vg ( vg - > cmd , vg , handle , & _pvs_single ) ;
2014-12-01 17:40:03 +03:00
break ;
case PVSEGS :
2015-02-13 12:36:06 +03:00
r = process_each_pv_in_vg ( vg - > cmd , vg , handle ,
2014-12-01 17:40:03 +03:00
do_lv_info & & ! do_lv_seg_status ? & _pvsegs_with_lv_info_single :
! do_lv_info & & do_lv_seg_status ? & _pvsegs_with_lv_status_single :
do_lv_info & & do_lv_seg_status ? & _pvsegs_with_lv_info_and_status_single :
& _pvsegs_single ) ;
break ;
default :
log_error ( INTERNAL_ERROR " %s for VGS " , incorrect_report_type_msg ) ;
break ;
}
break ;
case PVS :
switch ( sh - > report_type ) {
case PVS :
2015-02-13 12:36:06 +03:00
r = _pvs_single ( vg - > cmd , vg , pv , handle ) ;
2014-12-01 17:40:03 +03:00
break ;
case PVSEGS :
2015-02-13 12:36:06 +03:00
r = process_each_segment_in_pv ( vg - > cmd , vg , pv , handle ,
2014-12-01 17:40:03 +03:00
do_lv_info & & ! do_lv_seg_status ? & _pvsegs_with_lv_info_sub_single :
! do_lv_info & & do_lv_seg_status ? & _pvsegs_with_lv_status_sub_single :
do_lv_info & & do_lv_seg_status ? & _pvsegs_with_lv_info_and_status_sub_single :
& _pvsegs_sub_single ) ;
break ;
default :
log_error ( INTERNAL_ERROR " %s for PVS " , incorrect_report_type_msg ) ;
break ;
}
break ;
default :
log_error ( INTERNAL_ERROR " %s " , incorrect_report_type_msg ) ;
break ;
}
2015-02-13 12:36:06 +03:00
/*
* Keep the selection handle provided from the caller -
* do not destroy it - the caller will still use it to
* pass the result through it to layers above .
*/
handle - > selection_handle = NULL ;
2015-02-13 12:42:21 +03:00
destroy_processing_handle ( cmd , handle ) ;
2014-12-01 17:40:03 +03:00
return r ;
2014-12-01 16:19:30 +03:00
}
2015-02-27 15:32:52 +03:00
static void _check_pv_list ( struct cmd_context * cmd , int argc , char * * argv ,
report_type_t * report_type , unsigned * args_are_pvs )
{
unsigned i ;
int rescan_done = 0 ;
* args_are_pvs = ( * report_type = = PVS | |
* report_type = = LABEL | |
* report_type = = PVSEGS ) ? 1 : 0 ;
2015-03-02 12:36:32 +03:00
if ( * args_are_pvs & & argc ) {
2015-02-27 15:32:52 +03:00
for ( i = 0 ; i < argc ; i + + ) {
2015-02-27 16:52:31 +03:00
if ( ! rescan_done & & ! dev_cache_get ( argv [ i ] , cmd - > full_filter ) ) {
2015-02-27 15:32:52 +03:00
cmd - > filter - > wipe ( cmd - > filter ) ;
/* FIXME scan only one device */
lvmcache_label_scan ( cmd , 0 ) ;
rescan_done = 1 ;
}
if ( * argv [ i ] = = ' @ ' ) {
2015-02-27 15:48:47 +03:00
/*
* Tags are metadata related , not label
* related , change report type accordingly !
*/
2015-02-27 15:32:52 +03:00
if ( * report_type = = LABEL )
* report_type = PVS ;
/*
* If we changed the report_type and we did rescan ,
* no need to iterate over dev list further - nothing
* else would change .
*/
if ( rescan_done )
break ;
}
}
}
}
2015-10-22 15:30:11 +03:00
static void _del_option_from_list ( struct dm_list * sll , const char * prefix ,
size_t prefix_len , const char * str )
2015-10-21 16:36:26 +03:00
{
struct dm_list * slh ;
struct dm_str_list * sl ;
2015-10-22 15:30:11 +03:00
const char * a = str , * b ;
2015-10-21 16:36:26 +03:00
2015-10-22 15:30:11 +03:00
prefix_len - - ;
2015-10-21 16:36:26 +03:00
dm_list_uniterate ( slh , sll , sll ) {
sl = dm_list_item ( slh , struct dm_str_list ) ;
2015-10-22 15:30:11 +03:00
/* exact match */
2015-10-21 16:36:26 +03:00
if ( ! strcmp ( str , sl - > str ) ) {
dm_list_del ( slh ) ;
return ;
}
2015-10-22 15:30:11 +03:00
/* also try to match with known prefix */
b = sl - > str ;
if ( ! strncmp ( prefix , a , prefix_len ) ) {
a + = prefix_len ;
if ( * a = = ' _ ' )
a + + ;
}
if ( ! strncmp ( prefix , b , prefix_len ) ) {
b + = prefix_len ;
if ( * b = = ' _ ' )
b + + ;
}
if ( ! strcmp ( a , b ) ) {
dm_list_del ( slh ) ;
return ;
}
2015-10-21 16:36:26 +03:00
}
}
2015-10-22 15:30:11 +03:00
static int _get_report_options ( struct cmd_context * cmd ,
report_type_t report_type ,
2015-10-22 16:37:27 +03:00
const char * * options ,
const char * * fields_to_compact )
2015-10-20 17:36:11 +03:00
{
2015-10-22 15:30:11 +03:00
const char * prefix = report_get_field_prefix ( report_type ) ;
size_t prefix_len = strlen ( prefix ) ;
2015-10-21 15:57:49 +03:00
struct arg_value_group_list * current_group ;
struct dm_list * final_opts_list ;
2015-10-22 16:37:27 +03:00
struct dm_list * final_compact_list = NULL ;
2015-10-21 15:57:49 +03:00
struct dm_list * opts_list = NULL ;
2015-10-21 16:36:26 +03:00
struct dm_str_list * sl ;
2015-10-20 17:36:11 +03:00
const char * opts ;
2015-11-11 18:09:39 +03:00
struct dm_pool * mem ;
2015-10-21 15:57:49 +03:00
int r = ECMD_PROCESSED ;
2015-10-20 17:36:11 +03:00
2015-11-11 18:09:39 +03:00
if ( ! ( mem = dm_pool_create ( " report_options " , 128 ) ) ) {
log_error ( " Failed to create temporary mempool to process report options. " ) ;
2015-11-12 00:07:39 +03:00
return ECMD_FAILED ;
2015-11-11 18:09:39 +03:00
}
2015-10-22 16:37:27 +03:00
2015-11-11 18:09:39 +03:00
if ( ! ( final_opts_list = str_to_str_list ( mem , * options , " , " , 1 ) ) ) {
2015-10-21 15:57:49 +03:00
r = ECMD_FAILED ;
goto_out ;
2015-10-20 17:36:11 +03:00
}
2015-10-21 15:57:49 +03:00
dm_list_iterate_items ( current_group , & cmd - > arg_value_groups ) {
if ( ! grouped_arg_is_set ( current_group - > arg_values , options_ARG ) )
continue ;
opts = grouped_arg_str_value ( current_group - > arg_values , options_ARG , NULL ) ;
if ( ! opts | | ! * opts ) {
log_error ( " Invalid options string: %s " , opts ) ;
r = EINVALID_CMD_LINE ;
goto out ;
2015-10-20 17:36:11 +03:00
}
2015-10-21 15:57:49 +03:00
switch ( * opts ) {
case ' + ' :
2015-10-21 16:36:26 +03:00
/* fall through */
case ' - ' :
2015-10-22 16:37:27 +03:00
/* fall through */
case ' # ' :
2015-11-11 18:09:39 +03:00
if ( ! ( opts_list = str_to_str_list ( mem , opts + 1 , " , " , 1 ) ) ) {
2015-10-21 15:57:49 +03:00
r = ECMD_FAILED ;
goto_out ;
}
2015-10-21 16:36:26 +03:00
if ( * opts = = ' + ' ) {
dm_list_splice ( final_opts_list , opts_list ) ;
} else if ( * opts = = ' - ' ) {
dm_list_iterate_items ( sl , opts_list )
2015-10-22 15:30:11 +03:00
_del_option_from_list ( final_opts_list , prefix ,
prefix_len , sl - > str ) ;
2015-10-22 16:37:27 +03:00
} else if ( * opts = = ' # ' ) {
2015-11-11 18:09:39 +03:00
if ( ! final_compact_list )
2015-10-22 16:37:27 +03:00
final_compact_list = opts_list ;
2015-11-11 18:09:39 +03:00
else
2015-10-22 16:37:27 +03:00
dm_list_splice ( final_compact_list , opts_list ) ;
2015-10-21 16:36:26 +03:00
}
2015-10-21 15:57:49 +03:00
break ;
default :
2015-11-11 18:09:39 +03:00
if ( ! ( final_opts_list = str_to_str_list ( mem , opts , " , " , 1 ) ) ) {
2015-10-21 15:57:49 +03:00
r = ECMD_FAILED ;
2015-11-12 00:07:39 +03:00
goto_out ;
2015-10-21 15:57:49 +03:00
}
}
}
if ( ! ( * options = str_list_to_str ( cmd - > mem , final_opts_list , " , " ) ) ) {
r = ECMD_FAILED ;
2015-11-12 00:07:39 +03:00
goto_out ;
2015-10-21 15:57:49 +03:00
}
2015-10-22 16:37:27 +03:00
if ( final_compact_list & &
! ( * fields_to_compact = str_list_to_str ( cmd - > mem , final_compact_list , " , " ) ) ) {
dm_pool_free ( cmd - > mem , ( char * ) * options ) ;
r = ECMD_FAILED ;
2015-11-12 00:07:39 +03:00
goto_out ;
2015-10-22 16:37:27 +03:00
}
2015-10-21 15:57:49 +03:00
out :
2015-11-12 00:07:39 +03:00
dm_pool_destroy ( mem ) ;
2015-10-21 15:57:49 +03:00
return r ;
2015-10-20 17:36:11 +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 ;
2014-11-27 17:02:13 +03:00
struct processing_handle handle = { 0 } ;
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-12-01 16:04:29 +03:00
unsigned args_are_pvs ;
int lv_info_needed , lv_segment_status_needed ;
2014-10-07 03:34:04 +04:00
int lock_global = 0 ;
2015-10-22 16:37:27 +03:00
const char * fields_to_compact = NULL ;
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
2015-03-05 23:00:44 +03:00
/*
* Include foreign VGs that contain active LVs .
* That shouldn ' t happen in general , but if it does by some
* mistake , then we want to display those VGs and allow the
* LVs to be deactivated .
*/
cmd - > include_active_foreign_vgs = 1 ;
2015-02-27 15:32:52 +03:00
/* Check PV specifics and do extra changes/actions if needed. */
_check_pv_list ( cmd , argc , argv , & report_type , & args_are_pvs ) ;
2014-04-01 16:46:22 +04:00
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 */
2015-10-20 17:36:11 +03:00
if ( arg_count ( cmd , options_ARG ) & &
2015-10-22 16:37:27 +03:00
( ( r = _get_report_options ( cmd , report_type , & options , & fields_to_compact ) ! = ECMD_PROCESSED ) ) )
2015-10-20 17:36:11 +03:00
return r ;
2002-12-12 23:55:49 +03:00
/* -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-12-01 16:04:29 +03:00
if ( ! _get_final_report_type ( args_are_pvs ,
report_type , & lv_info_needed ,
& lv_segment_status_needed ,
& report_type ) ) {
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
}
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 ;
}
}
2014-11-27 17:02:13 +03:00
handle . internal_report_for_select = 0 ;
handle . custom_handle = report_handle ;
2002-12-12 23:55:49 +03:00
switch ( report_type ) {
2013-09-18 04:09:15 +04:00
case DEVTYPES :
2014-11-27 17:02:13 +03:00
r = _process_each_devtype ( cmd , argc , & handle ) ;
2013-09-18 04:09:15 +04:00
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 :
2014-11-27 17:02:13 +03:00
r = process_each_lv ( cmd , argc , argv , 0 , & 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 ,
2014-11-27 17:02:13 +03:00
& 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 ,
2014-11-27 17:02:13 +03:00
& 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-11-27 17:02:13 +03:00
& 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 ,
2014-11-27 17:02:13 +03:00
& 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 :
2014-11-27 17:02:13 +03:00
r = process_each_lv ( cmd , argc , argv , 0 , & 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-11-27 17:02:13 +03:00
& 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 ,
2014-11-27 17:02:13 +03:00
& handle , & _pvsegs_in_vg ) ;
2005-04-20 00:58:25 +04:00
break ;
2002-12-12 23:55:49 +03:00
}
2015-10-16 17:25:51 +03:00
if ( find_config_tree_bool ( cmd , report_compact_output_CFG , NULL ) ) {
if ( ! dm_report_compact_fields ( report_handle ) )
log_error ( " Failed to compact report output. " ) ;
2015-10-22 16:37:27 +03:00
} else if ( fields_to_compact | |
( fields_to_compact = find_config_tree_str_allow_empty ( cmd , report_compact_output_cols_CFG , NULL ) ) ) {
2015-10-16 17:25:51 +03:00
if ( ! dm_report_compact_given_fields ( report_handle , fields_to_compact ) )
log_error ( " Failed to compact given columns in report output. " ) ;
}
2014-12-05 13:46:26 +03:00
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 ) ;
}