2002-12-12 23:55:49 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2002 - 2004 Sistina Software , Inc . All rights reserved .
2013-02-05 16:59:15 +04:00
* Copyright ( C ) 2004 - 2013 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 "lib.h"
# include "metadata.h"
# include "report.h"
# include "toolcontext.h"
# include "lvm-string.h"
# include "display.h"
# include "activate.h"
2004-09-16 22:40:56 +04:00
# include "segtype.h"
2007-01-16 21:06:12 +03:00
# include "lvmcache.h"
2013-09-18 04:09:15 +04:00
# include "device-types.h"
2002-12-12 23:55:49 +03:00
2010-01-07 17:37:11 +03:00
# include <stddef.h> /* offsetof() */
2007-01-16 21:06:12 +03:00
struct lvm_report_object {
struct volume_group * vg ;
struct logical_volume * lv ;
struct physical_volume * pv ;
struct lv_segment * seg ;
struct pv_segment * pvseg ;
} ;
2010-02-15 23:27:33 +03:00
static const uint64_t _minusone64 = UINT64_C ( - 1 ) ;
static const int32_t _minusone32 = INT32_C ( - 1 ) ;
2013-06-15 04:24:16 +04:00
static const uint64_t _zero64 = UINT64_C ( 0 ) ;
2007-11-09 19:51:54 +03:00
2013-09-23 12:02:01 +04:00
static int _field_set_value ( struct dm_report_field * field , const void * data , const void * sort )
{
dm_report_field_set_value ( field , data , sort ) ;
return 1 ;
}
static int _field_set_percent ( struct dm_report_field * field ,
struct dm_pool * mem ,
percent_t percent )
{
char * repstr ;
uint64_t * sortval ;
if ( percent = = PERCENT_INVALID )
// FIXME maybe use here '--'?
return _field_set_value ( field , " " , & _minusone64 ) ;
if ( ! ( repstr = dm_pool_alloc ( mem , 8 ) ) | |
! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
if ( repstr )
dm_pool_free ( mem , repstr ) ;
log_error ( " dm_pool_alloc failed. " ) ;
return 0 ;
}
if ( dm_snprintf ( repstr , 7 , " %.2f " , percent_to_float ( percent ) ) < 0 ) {
dm_pool_free ( mem , repstr ) ;
log_error ( " Percentage too large. " ) ;
return 0 ;
}
* sortval = ( uint64_t ) ( percent * 1000.f ) ;
return _field_set_value ( field , repstr , sortval ) ;
}
2002-12-12 23:55:49 +03:00
/*
* Data - munging functions to prepare each data type for display and sorting
*/
2010-07-09 19:34:40 +04:00
static int _string_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2011-02-18 17:47:28 +03:00
return dm_report_field_string ( rh , field , ( const char * const * ) data ) ;
2002-12-12 23:55:49 +03:00
}
2013-09-18 04:09:15 +04:00
static int _chars_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
return dm_report_field_string ( rh , field , ( const char * const * ) & data ) ;
}
2010-07-09 19:34:40 +04:00
static int _dev_name_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2010-02-15 21:34:00 +03:00
const char * name = dev_name ( * ( const struct device * const * ) data ) ;
2002-12-12 23:55:49 +03:00
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field , & name ) ;
2002-12-12 23:55:49 +03:00
}
2011-04-12 16:24:29 +04:00
static int _devices_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
2004-05-05 14:58:44 +04:00
{
2011-04-12 16:24:29 +04:00
char * str ;
if ( ! ( str = lvseg_devices ( mem , ( const struct lv_segment * ) data ) ) )
2004-05-05 14:58:44 +04:00
return 0 ;
2011-04-12 16:24:29 +04:00
dm_report_field_set_value ( field , str , NULL ) ;
2004-05-05 14:58:44 +04:00
return 1 ;
}
2006-10-03 21:55:20 +04:00
2010-07-09 19:34:40 +04:00
static int _peranges_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-12-15 00:53:02 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2007-12-15 00:53:02 +03:00
{
2011-04-12 16:24:29 +04:00
char * str ;
if ( ! ( str = lvseg_seg_pe_ranges ( mem , ( const struct lv_segment * ) data ) ) )
return 0 ;
dm_report_field_set_value ( field , str , NULL ) ;
return 1 ;
2007-12-15 00:53:02 +03:00
}
2010-07-09 19:34:40 +04:00
static int _tags_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2004-03-08 20:19:15 +03:00
{
2008-11-04 01:14:30 +03:00
const struct dm_list * tags = ( const struct dm_list * ) data ;
2010-09-30 18:08:07 +04:00
char * tags_str ;
2004-03-08 20:19:15 +03:00
2010-09-30 18:08:07 +04:00
if ( ! ( tags_str = tags_format_and_copy ( mem , tags ) ) )
2004-03-08 20:19:15 +03:00
return 0 ;
2010-09-30 18:08:07 +04:00
dm_report_field_set_value ( field , tags_str , NULL ) ;
2004-03-08 20:19:15 +03:00
return 1 ;
}
2007-01-16 21:06:12 +03:00
static int _modules_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2006-10-03 21:55:20 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-10-12 20:13:06 +04:00
char * modules_str ;
2006-10-03 21:55:20 +04:00
2010-10-12 20:13:06 +04:00
if ( ! ( modules_str = lv_modules_dup ( mem , lv ) ) )
2006-10-03 21:55:20 +04:00
return 0 ;
2010-10-12 20:13:06 +04:00
dm_report_field_set_value ( field , modules_str , NULL ) ;
return 1 ;
2006-10-03 21:55:20 +04:00
}
2013-07-02 16:34:52 +04:00
static int _lvprofile_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( lv - > profile )
return dm_report_field_string ( rh , field , & lv - > profile - > name ) ;
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2007-01-16 21:06:12 +03:00
static int _vgfmt_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct volume_group * vg = ( const struct volume_group * ) data ;
2002-12-12 23:55:49 +03:00
if ( ! vg - > fid ) {
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2007-01-16 21:06:12 +03:00
return _string_disp ( rh , mem , field , & vg - > fid - > fmt - > name , private ) ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static int _pvfmt_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2002-12-12 23:55:49 +03:00
if ( ! pv - > fmt ) {
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2007-01-16 21:06:12 +03:00
return _string_disp ( rh , mem , field , & pv - > fmt - > name , private ) ;
2002-12-12 23:55:49 +03:00
}
2010-07-09 19:34:40 +04:00
static int _lvkmaj_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2004-07-04 02:07:52 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-10-12 20:12:33 +04:00
int major ;
2004-07-04 02:07:52 +04:00
2010-10-12 20:12:33 +04:00
if ( ( major = lv_kernel_major ( lv ) ) > = 0 )
return dm_report_field_int ( rh , field , & major ) ;
2004-07-04 02:07:52 +04:00
2010-02-15 23:27:33 +03:00
return dm_report_field_int32 ( rh , field , & _minusone32 ) ;
2004-07-04 02:07:52 +04:00
}
2010-07-09 19:34:40 +04:00
static int _lvkmin_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2004-07-04 02:07:52 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-10-12 20:12:33 +04:00
int minor ;
2004-07-04 02:07:52 +04:00
2010-10-12 20:12:33 +04:00
if ( ( minor = lv_kernel_minor ( lv ) ) > = 0 )
return dm_report_field_int ( rh , field , & minor ) ;
2004-07-04 02:07:52 +04:00
2010-02-15 23:27:33 +03:00
return dm_report_field_int32 ( rh , field , & _minusone32 ) ;
2004-07-04 02:07:52 +04:00
}
2010-07-09 19:34:40 +04:00
static int _lvstatus_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
char * repstr ;
2002-12-12 23:55:49 +03:00
2010-09-30 17:52:55 +04:00
if ( ! ( repstr = lv_attr_dup ( mem , lv ) ) )
2002-12-12 23:55:49 +03:00
return 0 ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _pvstatus_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2010-09-30 17:52:55 +04:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2002-12-20 02:25:55 +03:00
char * repstr ;
2002-12-12 23:55:49 +03:00
2010-09-30 17:52:55 +04:00
if ( ! ( repstr = pv_attr_dup ( mem , pv ) ) )
2002-12-12 23:55:49 +03:00
return 0 ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _vgstatus_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2004-05-19 02:12:53 +04:00
const struct volume_group * vg = ( const struct volume_group * ) data ;
2002-12-20 02:25:55 +03:00
char * repstr ;
2002-12-12 23:55:49 +03:00
2010-09-30 17:52:55 +04:00
if ( ! ( repstr = vg_attr_dup ( mem , vg ) ) )
2002-12-12 23:55:49 +03:00
return 0 ;
2005-08-16 03:34:11 +04:00
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _segtype_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
2010-11-17 23:08:14 +03:00
char * name ;
2011-03-05 15:14:00 +03:00
if ( ! ( name = lvseg_segtype_dup ( mem , seg ) ) ) {
log_error ( " Failed to get segtype. " ) ;
return 0 ;
}
2010-11-17 23:08:14 +03:00
dm_report_field_set_value ( field , name , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _loglv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2005-06-01 20:51:55 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-10-12 20:12:50 +04:00
const char * name ;
2005-06-01 20:51:55 +04:00
2010-10-12 20:12:50 +04:00
if ( ( name = lv_mirror_log_dup ( mem , lv ) ) )
return dm_report_field_string ( rh , field , & name ) ;
2005-06-01 20:51:55 +04:00
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , NULL ) ;
2005-06-01 20:51:55 +04:00
return 1 ;
}
2007-01-16 21:06:12 +03:00
static int _lvname_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2005-06-03 18:49:51 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2007-01-16 21:06:12 +03:00
char * repstr , * lvname ;
2005-06-03 18:49:51 +04:00
size_t len ;
2011-02-18 17:47:28 +03:00
if ( lv_is_visible ( lv ) )
return dm_report_field_string ( rh , field , & lv - > name ) ;
2005-06-03 18:49:51 +04:00
len = strlen ( lv - > name ) + 3 ;
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_zalloc ( mem , len ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2005-06-03 18:49:51 +04:00
return 0 ;
}
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( repstr , len , " [%s] " , lv - > name ) < 0 ) {
2005-06-03 18:49:51 +04:00
log_error ( " lvname snprintf failed " ) ;
return 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! ( lvname = dm_pool_strdup ( mem , lv - > name ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_strdup failed " ) ;
2005-06-03 18:49:51 +04:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , lvname ) ;
2005-06-03 18:49:51 +04:00
return 1 ;
}
2012-01-19 19:34:32 +04:00
static int _datalv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-06-15 00:02:12 +04:00
const struct lv_segment * seg = lv_is_thin_pool ( lv ) ? first_seg ( lv ) : NULL ;
2012-01-19 19:34:32 +04:00
2013-06-15 00:02:12 +04:00
if ( seg )
return _lvname_disp ( rh , mem , field , seg_lv ( seg , 0 ) , private ) ;
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
static int _metadatalv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-06-15 00:02:12 +04:00
const struct lv_segment * seg = lv_is_thin_pool ( lv ) ? first_seg ( lv ) : NULL ;
2012-01-19 19:34:32 +04:00
2013-06-15 00:02:12 +04:00
if ( seg )
return _lvname_disp ( rh , mem , field , seg - > metadata_lv , private ) ;
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
static int _poollv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-09-23 11:44:53 +04:00
struct lv_segment * seg = lv_is_thin_volume ( lv ) ? first_seg ( lv ) : NULL ;
2012-01-19 19:34:32 +04:00
2013-09-23 11:44:53 +04:00
if ( seg )
return _lvname_disp ( rh , mem , field , seg - > pool_lv , private ) ;
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2010-06-23 16:32:08 +04:00
static int _lvpath_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2010-06-23 16:32:08 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
char * repstr ;
2010-10-12 20:11:34 +04:00
if ( ! ( repstr = lv_path_dup ( mem , lv ) ) )
2010-06-23 16:32:08 +04:00
return 0 ;
dm_report_field_set_value ( field , repstr , NULL ) ;
return 1 ;
}
2009-04-25 05:17:59 +04:00
static int _origin_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( lv_is_cow ( lv ) )
return _lvname_disp ( rh , mem , field , origin_from_cow ( lv ) , private ) ;
2011-11-07 15:03:47 +04:00
if ( lv_is_thin_volume ( lv ) & & first_seg ( lv ) - > origin )
return _lvname_disp ( rh , mem , field , first_seg ( lv ) - > origin , private ) ;
2013-01-15 18:16:16 +04:00
if ( lv_is_thin_volume ( lv ) & & first_seg ( lv ) - > external_lv )
return _lvname_disp ( rh , mem , field , first_seg ( lv ) - > external_lv , private ) ;
2009-04-25 05:17:59 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _movepv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2003-05-06 16:06:02 +04:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
const char * name ;
2010-10-12 20:12:02 +04:00
if ( ! ( name = lv_move_pv_dup ( mem , lv ) ) )
dm_report_field_set_value ( field , " " , NULL ) ;
else
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field , & name ) ;
2003-05-06 16:06:02 +04:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _convertlv_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2008-01-10 21:35:51 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2008-01-10 21:35:51 +03:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
const char * name = NULL ;
2010-10-12 20:12:18 +04:00
name = lv_convert_lv_dup ( mem , lv ) ;
2008-01-10 21:35:51 +03:00
if ( name )
return dm_report_field_string ( rh , field , & name ) ;
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _size32_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const uint32_t size = * ( const uint32_t * ) data ;
2007-01-16 21:06:12 +03:00
const char * disp , * repstr ;
2002-12-20 02:25:55 +03:00
uint64_t * sortval ;
2002-12-12 23:55:49 +03:00
2008-01-30 16:19:47 +03:00
if ( ! * ( disp = display_size_units ( private , ( uint64_t ) size ) ) )
return_0 ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_strdup ( mem , disp ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_strdup failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2011-08-04 18:30:51 +04:00
* sortval = ( uint64_t ) size ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , sortval ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _size64_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2007-08-22 18:38:18 +04:00
struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const uint64_t size = * ( const uint64_t * ) data ;
2007-01-16 21:06:12 +03:00
const char * disp , * repstr ;
2002-12-20 02:25:55 +03:00
uint64_t * sortval ;
2002-12-12 23:55:49 +03:00
2008-01-30 16:19:47 +03:00
if ( ! * ( disp = display_size_units ( private , size ) ) )
return_0 ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_strdup ( mem , disp ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_strdup failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2002-12-20 02:25:55 +03:00
* sortval = size ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , sortval ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2012-01-19 19:34:32 +04:00
static int _uint32_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
return dm_report_field_uint32 ( rh , field , data ) ;
}
2013-09-18 04:09:15 +04:00
static int _int8_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
const int32_t val = * ( const int8_t * ) data ;
return dm_report_field_int32 ( rh , field , & val ) ;
}
2012-01-19 19:34:32 +04:00
static int _int32_disp ( struct dm_report * rh , struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data , void * private __attribute__ ( ( unused ) ) )
{
return dm_report_field_int32 ( rh , field , data ) ;
}
2007-11-09 19:51:54 +03:00
static int _lvreadahead_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2007-11-09 19:51:54 +03:00
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( lv - > read_ahead = = DM_READ_AHEAD_AUTO ) {
2010-02-15 23:27:33 +03:00
dm_report_field_set_value ( field , " auto " , & _minusone64 ) ;
2007-11-09 19:51:54 +03:00
return 1 ;
}
2007-11-14 03:08:25 +03:00
return _size32_disp ( rh , mem , field , & lv - > read_ahead , private ) ;
2007-11-09 19:51:54 +03:00
}
static int _lvkreadahead_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
2007-11-14 03:08:25 +03:00
void * private )
2007-11-09 19:51:54 +03:00
{
2007-11-12 23:51:54 +03:00
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t read_ahead = lv_kernel_read_ahead ( lv ) ;
2007-11-12 23:51:54 +03:00
2013-09-23 11:44:53 +04:00
if ( read_ahead = = UINT32_MAX )
2010-02-15 23:27:33 +03:00
return dm_report_field_int32 ( rh , field , & _minusone32 ) ;
2007-11-12 23:51:54 +03:00
2010-10-21 18:49:31 +04:00
return _size32_disp ( rh , mem , field , & read_ahead , private ) ;
2007-11-09 19:51:54 +03:00
}
2007-01-16 21:06:12 +03:00
static int _vgsize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = vg_size ( vg ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & size , private ) ;
2002-12-12 23:55:49 +03:00
}
2013-04-25 14:07:57 +04:00
static int _segmonitor_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
char * str ;
if ( ! ( str = lvseg_monitor_dup ( mem , ( const struct lv_segment * ) data ) ) )
return_0 ;
dm_report_field_set_value ( field , str , NULL ) ;
return 1 ;
}
2007-01-16 21:06:12 +03:00
static int _segstart_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t start = lvseg_start ( seg ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & start , private ) ;
2002-12-12 23:55:49 +03:00
}
2007-12-20 19:49:37 +03:00
static int _segstartpe_disp ( struct dm_report * rh ,
2010-07-09 19:34:40 +04:00
struct dm_pool * mem __attribute__ ( ( unused ) ) ,
2007-12-20 19:49:37 +03:00
struct dm_report_field * field ,
const void * data ,
2010-07-09 19:34:40 +04:00
void * private __attribute__ ( ( unused ) ) )
2007-12-15 00:53:02 +03:00
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
return dm_report_field_uint32 ( rh , field , & seg - > le ) ;
}
2007-01-16 21:06:12 +03:00
static int _segsize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = lvseg_size ( seg ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & size , private ) ;
2002-12-12 23:55:49 +03:00
}
2013-09-24 00:50:14 +04:00
static int _segsizepe_disp ( struct dm_report * rh ,
struct dm_pool * mem __attribute__ ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
return dm_report_field_uint32 ( rh , field , & seg - > len ) ;
}
2007-01-16 21:06:12 +03:00
static int _chunksize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2005-09-23 21:06:01 +04:00
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = lvseg_chunksize ( seg ) ;
2009-04-25 05:17:59 +04:00
return _size64_disp ( rh , mem , field , & size , private ) ;
}
2012-01-19 19:34:32 +04:00
static int _thinzero_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
/* Suppress thin count if not thin pool */
if ( ! seg_is_thin_pool ( seg ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return _uint32_disp ( rh , mem , field , & seg - > zero_new_blocks , private ) ;
}
static int _transactionid_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
/* Suppress thin count if not thin pool */
if ( ! seg_is_thin_pool ( seg ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return dm_report_field_uint64 ( rh , field , & seg - > transaction_id ) ;
}
2012-08-08 00:24:41 +04:00
static int _discards_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2012-07-09 18:48:28 +04:00
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
2012-08-08 00:24:41 +04:00
const char * discards_str ;
2012-07-09 18:48:28 +04:00
if ( seg_is_thin_volume ( seg ) )
seg = first_seg ( seg - > pool_lv ) ;
if ( seg_is_thin_pool ( seg ) ) {
2012-08-08 00:24:41 +04:00
discards_str = get_pool_discards_name ( seg - > discards ) ;
return dm_report_field_string ( rh , field , & discards_str ) ;
2012-08-07 21:48:34 +04:00
}
2012-07-09 18:48:28 +04:00
2012-08-07 21:48:34 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
2012-07-09 18:48:28 +04:00
return 1 ;
}
2012-01-19 19:34:32 +04:00
2009-04-25 05:17:59 +04:00
static int _originsize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = lv_origin_size ( lv ) ;
2009-04-25 05:17:59 +04:00
2013-09-23 11:44:53 +04:00
if ( size )
return _size64_disp ( rh , mem , field , & size , private ) ;
2005-09-23 21:06:01 +04:00
2013-09-23 11:44:53 +04:00
dm_report_field_set_value ( field , " " , & _zero64 ) ;
return 1 ;
2005-09-23 21:06:01 +04:00
}
2007-01-16 21:06:12 +03:00
static int _pvused_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t used = pv_used ( pv ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & used , private ) ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static int _pvfree_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t freespace = pv_free ( pv ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & freespace , private ) ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static int _pvsize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = pv_size_field ( pv ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & size , private ) ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static int _devsize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2004-08-11 17:15:05 +04:00
{
2010-02-14 06:21:37 +03:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t size = pv_dev_size ( pv ) ;
2004-08-11 17:15:05 +04:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & size , private ) ;
2004-08-11 17:15:05 +04:00
}
2007-01-16 21:06:12 +03:00
static int _vgfree_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t freespace = vg_free ( vg ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & freespace , private ) ;
2002-12-12 23:55:49 +03:00
}
2010-07-09 19:34:40 +04:00
static int _uuid_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
char * repstr = NULL ;
2011-02-18 17:47:28 +03:00
if ( ! ( repstr = id_format_and_copy ( mem , data ) ) )
2008-01-30 16:19:47 +03:00
return_0 ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2007-07-09 19:40:43 +04:00
static int _pvmdas_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
2009-07-26 16:41:09 +04:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = pv_mda_count ( pv ) ;
2007-07-09 19:40:43 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
Define new functions and vgs/pvs fields related to mda ignore.
Define a new pvs field, pv_mda_used_count, and a new vgs field,
vg_mda_used_count to match the existing pv_mda_count and vg_mda_count.
These new fields count the number of mdas that have the 'ignored' bit
clear (they are in use on the PV / VG). Also define various supporting
functions to implement the counting as well as setting the ignored
flag and determining if an mda is ignored. These high level functions
call into the lower level location independent mda ignore functions
defined by earlier patches.
Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda. The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on. The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts. Also, pv_mda_set_ignored must search both vg
lists for ignored mda. If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.
Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv. Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:33:44 +04:00
static int _pvmdasused_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = pv_mda_used_count ( pv ) ;
Define new functions and vgs/pvs fields related to mda ignore.
Define a new pvs field, pv_mda_used_count, and a new vgs field,
vg_mda_used_count to match the existing pv_mda_count and vg_mda_count.
These new fields count the number of mdas that have the 'ignored' bit
clear (they are in use on the PV / VG). Also define various supporting
functions to implement the counting as well as setting the ignored
flag and determining if an mda is ignored. These high level functions
call into the lower level location independent mda ignore functions
defined by earlier patches.
Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda. The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on. The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts. Also, pv_mda_set_ignored must search both vg
lists for ignored mda. If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.
Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv. Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:33:44 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2007-07-09 19:40:43 +04:00
static int _vgmdas_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = vg_mda_count ( vg ) ;
2007-07-09 19:40:43 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
Define new functions and vgs/pvs fields related to mda ignore.
Define a new pvs field, pv_mda_used_count, and a new vgs field,
vg_mda_used_count to match the existing pv_mda_count and vg_mda_count.
These new fields count the number of mdas that have the 'ignored' bit
clear (they are in use on the PV / VG). Also define various supporting
functions to implement the counting as well as setting the ignored
flag and determining if an mda is ignored. These high level functions
call into the lower level location independent mda ignore functions
defined by earlier patches.
Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda. The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on. The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts. Also, pv_mda_set_ignored must search both vg
lists for ignored mda. If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.
Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv. Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:33:44 +04:00
static int _vgmdasused_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = vg_mda_used_count ( vg ) ;
Define new functions and vgs/pvs fields related to mda ignore.
Define a new pvs field, pv_mda_used_count, and a new vgs field,
vg_mda_used_count to match the existing pv_mda_count and vg_mda_count.
These new fields count the number of mdas that have the 'ignored' bit
clear (they are in use on the PV / VG). Also define various supporting
functions to implement the counting as well as setting the ignored
flag and determining if an mda is ignored. These high level functions
call into the lower level location independent mda ignore functions
defined by earlier patches.
Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda. The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on. The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts. Also, pv_mda_set_ignored must search both vg
lists for ignored mda. If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.
Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv. Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:33:44 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2010-06-29 00:37:23 +04:00
static int _vgmdacopies_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = vg_mda_copies ( vg ) ;
2010-06-29 00:37:23 +04:00
Allow 'all' and 'unmanaged' values for --vgmetadatacopies.
Allowing an 'all' and 'unmanaged' value is more intuitive, and
provides a simple way for users to get back to original LVM behavior
of metadata written to all PVs in the volume group.
If the user requests "--vgmetadatacopies unmanaged", this instructs
LVM not to manage the ignore bits to achieve a specific number of
metadata copies in the volume group. The user is free to use
"pvchange --metadataignore" to control the mdas on a per-PV basis.
If the user requests "--vgmetadatacopies all", this instructs LVM
to do 2 things: 1) clear all ignore bits, and 2) set the "unmanaged"
policy going forward.
Internally, we use the special MAX_UINT32 value to indicate 'all'.
This 'just' works since it's the largest value possible for the
field and so all 'ignore' bits on all mdas in the VG will get
cleared inside _vg_metadata_balance(). However, after we've
called the _vg_metadata_balance function, we check for the special
'all' value, and if set, we write the "unmanaged" value into the
metadata. As such, the 'all' value is never written to disk.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 00:40:01 +04:00
if ( count = = VGMETADATACOPIES_UNMANAGED ) {
dm_report_field_set_value ( field , " unmanaged " , & _minusone64 ) ;
return 1 ;
}
2010-06-29 00:37:23 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2013-07-02 16:34:52 +04:00
static int _vgprofile_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
if ( vg - > profile )
return dm_report_field_string ( rh , field , & vg - > profile - > name ) ;
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2007-11-05 20:17:55 +03:00
static int _pvmdafree_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
2010-09-30 18:09:10 +04:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t freespace = pv_mda_free ( pv ) ;
2007-11-05 20:17:55 +03:00
return _size64_disp ( rh , mem , field , & freespace , private ) ;
}
2009-01-10 01:44:33 +03:00
static int _pvmdasize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
2010-09-30 18:09:10 +04:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t min_mda_size = pv_mda_size ( pv ) ;
2009-01-10 01:44:33 +03:00
return _size64_disp ( rh , mem , field , & min_mda_size , private ) ;
}
static int _vgmdasize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t min_mda_size = vg_mda_size ( vg ) ;
2009-01-10 01:44:33 +03:00
return _size64_disp ( rh , mem , field , & min_mda_size , private ) ;
}
2007-11-05 20:17:55 +03:00
static int _vgmdafree_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint64_t freespace = vg_mda_free ( vg ) ;
2007-11-05 20:17:55 +03:00
return _size64_disp ( rh , mem , field , & freespace , private ) ;
}
2008-04-10 21:19:02 +04:00
static int _lvcount_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = vg_visible_lvs ( vg ) ;
2008-04-10 21:19:02 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2007-01-16 21:06:12 +03:00
static int _lvsegcount_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = dm_list_size ( & lv - > segments ) ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
2002-12-12 23:55:49 +03:00
}
2009-05-12 23:12:09 +04:00
static int _snapcount_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct volume_group * vg = ( const struct volume_group * ) data ;
2013-09-23 11:44:53 +04:00
uint32_t count = snapshot_count ( vg ) ;
2009-05-12 23:12:09 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2010-07-09 19:34:40 +04:00
static int _snpercent_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) , struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2002-12-20 02:25:55 +03:00
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-11-30 14:53:31 +03:00
percent_t snap_percent ;
2002-12-20 02:25:55 +03:00
uint64_t * sortval ;
char * repstr ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
/* Suppress snapshot percentage if not using driver */
if ( ! activation ( ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
if ( ! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2010-01-13 04:55:43 +03:00
if ( ( ! lv_is_cow ( lv ) & & ! lv_is_merging_origin ( lv ) ) | |
2013-05-15 05:13:31 +04:00
! lv_is_active_locally ( lv ) ) {
2003-03-24 21:08:53 +03:00
* sortval = UINT64_C ( 0 ) ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , sortval ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-11-30 14:53:31 +03:00
if ( ! lv_snapshot_percent ( lv , & snap_percent ) | |
2012-01-21 02:02:04 +04:00
( snap_percent = = PERCENT_INVALID ) | | ( snap_percent = = PERCENT_MERGE_FAILED ) ) {
2010-01-13 04:55:43 +03:00
if ( ! lv_is_merging_origin ( lv ) ) {
2010-01-13 04:54:34 +03:00
* sortval = UINT64_C ( 100 ) ;
dm_report_field_set_value ( field , " 100.00 " , sortval ) ;
} else {
/* onactivate merge that hasn't started yet would
* otherwise display incorrect snap % in origin
*/
* sortval = UINT64_C ( 0 ) ;
dm_report_field_set_value ( field , " " , sortval ) ;
}
2003-01-21 21:50:50 +03:00
return 1 ;
}
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_zalloc ( mem , 8 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2010-11-30 14:53:31 +03:00
if ( dm_snprintf ( repstr , 7 , " %.2f " , percent_to_float ( snap_percent ) ) < 0 ) {
2002-12-12 23:55:49 +03:00
log_error ( " snapshot percentage too large " ) ;
return 0 ;
}
2010-02-15 21:35:06 +03:00
* sortval = ( uint64_t ) ( snap_percent * 1000.f ) ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , sortval ) ;
2002-12-20 02:25:55 +03:00
2002-12-12 23:55:49 +03:00
return 1 ;
}
2010-07-09 19:34:40 +04:00
static int _copypercent_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2009-10-01 05:04:27 +04:00
struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2010-07-09 19:34:40 +04:00
const void * data , void * private __attribute__ ( ( unused ) ) )
2003-05-06 16:06:02 +04:00
{
2011-02-18 17:47:28 +03:00
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
2010-11-30 14:53:31 +03:00
percent_t percent ;
2003-05-06 16:06:02 +04:00
uint64_t * sortval ;
char * repstr ;
2007-01-16 21:06:12 +03:00
if ( ! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2003-05-06 16:06:02 +04:00
return 0 ;
}
2012-10-24 06:19:27 +04:00
if ( lv - > status & RAID ) {
if ( ! lv_raid_percent ( lv , & percent ) | |
( percent = = PERCENT_INVALID ) )
goto no_copypercent ;
} else if ( ( ! ( lv - > status & PVMOVE ) & & ! ( lv - > status & MIRRORED ) ) | |
! lv_mirror_percent ( lv - > vg - > cmd , lv , 0 , & percent , NULL ) | |
( percent = = PERCENT_INVALID ) )
goto no_copypercent ;
2003-05-06 16:06:02 +04:00
2010-11-30 14:53:31 +03:00
percent = copy_percent ( lv ) ;
2003-05-06 16:06:02 +04:00
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_zalloc ( mem , 8 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2003-05-06 16:06:02 +04:00
return 0 ;
}
2010-11-30 14:53:31 +03:00
if ( dm_snprintf ( repstr , 7 , " %.2f " , percent_to_float ( percent ) ) < 0 ) {
2004-05-05 14:58:44 +04:00
log_error ( " copy percentage too large " ) ;
2003-05-06 16:06:02 +04:00
return 0 ;
}
2010-02-15 21:35:06 +03:00
* sortval = ( uint64_t ) ( percent * 1000.f ) ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , repstr , sortval ) ;
2003-05-06 16:06:02 +04:00
return 1 ;
2012-10-24 06:19:27 +04:00
no_copypercent :
* sortval = UINT64_C ( 0 ) ;
dm_report_field_set_value ( field , " " , sortval ) ;
return 1 ;
2003-05-06 16:06:02 +04:00
}
2013-07-19 04:30:02 +04:00
static int _raidsyncaction_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2013-04-12 00:33:59 +04:00
struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
char * sync_action ;
if ( ! ( lv - > status & RAID ) | |
! lv_raid_sync_action ( lv , & sync_action ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return _string_disp ( rh , mem , field , & sync_action , private ) ;
}
2013-07-19 04:30:02 +04:00
static int _raidmismatchcount_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2013-04-12 00:33:59 +04:00
struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
uint64_t mismatch_count ;
if ( ! ( lv - > status & RAID ) | |
! lv_raid_mismatch_count ( lv , & mismatch_count ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
return dm_report_field_uint64 ( rh , field , & mismatch_count ) ;
}
2013-07-19 04:30:02 +04:00
static int _raidwritebehind_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
RAID: Add writemostly/writebehind support for RAID1
'lvchange' is used to alter a RAID 1 logical volume's write-mostly and
write-behind characteristics. The '--writemostly' parameter takes a
PV as an argument with an optional trailing character to specify whether
to set ('y'), unset ('n'), or toggle ('t') the value. If no trailing
character is given, it will set the flag.
Synopsis:
lvchange [--writemostly <PV>:{t|y|n}] [--writebehind <count>] vg/lv
Example:
lvchange --writemostly /dev/sdb1:y --writebehind 512 vg/raid1_lv
The last character in the 'lv_attr' field is used to show whether a device
has the WriteMostly flag set. It is signified with a 'w'. If the device
has failed, the 'p'artial flag has priority.
Example ("nosync" raid1 with mismatch_cnt and writemostly):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg Rwi---r-m 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-w 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-- 1 linear 4.00m
Example (raid1 with mismatch_cnt, writemostly - but failed drive):
[~]# lvs -a --segment vg
LV VG Attr #Str Type SSize
raid1 vg rwi---r-p 2 raid1 500.00m
[raid1_rimage_0] vg Iwi---r-- 1 linear 500.00m
[raid1_rimage_1] vg Iwi---r-p 1 linear 500.00m
[raid1_rmeta_0] vg ewi---r-- 1 linear 4.00m
[raid1_rmeta_1] vg ewi---r-p 1 linear 4.00m
A new reportable field has been added for writebehind as well. If
write-behind has not been set or the LV is not RAID1, the field will
be blank.
Example (writebehind is set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r-- 512
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
Example (writebehind is not set):
[~]# lvs -a -o name,attr,writebehind vg
LV Attr WBehind
lv rwi-a-r--
[lv_rimage_0] iwi-aor-w
[lv_rimage_1] iwi-aor--
[lv_rmeta_0] ewi-aor--
[lv_rmeta_1] ewi-aor--
2013-04-15 22:59:46 +04:00
struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( ! lv_is_raid_type ( lv ) | | ! first_seg ( lv ) - > writebehind ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return dm_report_field_uint32 ( rh , field , & first_seg ( lv ) - > writebehind ) ;
2013-04-12 00:33:59 +04:00
}
2013-07-19 04:30:02 +04:00
static int _raidminrecoveryrate_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2013-05-31 20:25:52 +04:00
struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( ! lv_is_raid_type ( lv ) | | ! first_seg ( lv ) - > min_recovery_rate ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return dm_report_field_uint32 ( rh , field ,
& first_seg ( lv ) - > min_recovery_rate ) ;
}
2013-07-19 04:30:02 +04:00
static int _raidmaxrecoveryrate_disp ( struct dm_report * rh __attribute__ ( ( unused ) ) ,
2013-05-31 20:25:52 +04:00
struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data ,
void * private __attribute__ ( ( unused ) ) )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( ! lv_is_raid_type ( lv ) | | ! first_seg ( lv ) - > max_recovery_rate ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
return dm_report_field_uint32 ( rh , field ,
& first_seg ( lv ) - > max_recovery_rate ) ;
}
2013-09-23 13:01:46 +04:00
/* Called only with lv_is_thin_pool/volume */
static int _dtpercent_disp ( int metadata , struct dm_pool * mem ,
2012-01-19 19:34:32 +04:00
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
struct lvinfo info ;
percent_t percent ;
uint64_t * sortval ;
char * repstr ;
/* Suppress data percent if not thin pool/volume or not using driver */
2012-01-25 17:11:52 +04:00
if ( ! lv_info ( lv - > vg - > cmd , lv , 1 , & info , 0 , 0 ) | | ! info . exists ) {
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
if ( ! ( sortval = dm_pool_zalloc ( mem , sizeof ( uint64_t ) ) ) ) {
log_error ( " Failed to allocate sortval. " ) ;
return 0 ;
}
if ( lv_is_thin_pool ( lv ) ) {
if ( ! lv_thin_pool_percent ( lv , metadata , & percent ) )
return_0 ;
} else { /* thin_volume */
if ( ! lv_thin_percent ( lv , 0 , & percent ) )
return_0 ;
}
if ( ! ( repstr = dm_pool_alloc ( mem , 8 ) ) ) {
log_error ( " Failed to allocate report buffer. " ) ;
return 0 ;
}
if ( dm_snprintf ( repstr , 8 , " %.2f " , percent_to_float ( percent ) ) < 0 ) {
log_error ( " Data percentage too large. " ) ;
return 0 ;
}
* sortval = ( uint64_t ) ( percent * 1000.f ) ;
dm_report_field_set_value ( field , repstr , sortval ) ;
return 1 ;
}
static int _datapercent_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( lv_is_cow ( lv ) )
return _snpercent_disp ( rh , mem , field , data , private ) ;
if ( lv_is_thin_pool ( lv ) | | lv_is_thin_volume ( lv ) )
2013-09-23 13:01:46 +04:00
return _dtpercent_disp ( 0 , mem , field , data , private ) ;
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
static int _metadatapercent_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
if ( lv_is_thin_pool ( lv ) )
2013-09-23 13:01:46 +04:00
return _dtpercent_disp ( 1 , mem , field , data , private ) ;
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
static int _lvmetadatasize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
uint64_t size ;
if ( ! lv_is_thin_pool ( lv ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
size = lv_metadata_size ( lv ) ;
return _size64_disp ( rh , mem , field , & size , private ) ;
}
static int _thincount_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
uint32_t count ;
/* Suppress thin count if not thin pool */
if ( ! seg_is_thin_pool ( seg ) ) {
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
count = dm_list_size ( & seg - > lv - > segs_using_this_lv ) ;
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
static int _lvtime_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
char * repstr ;
uint64_t * sortval ;
2013-09-23 11:59:37 +04:00
if ( ! ( repstr = lv_time_dup ( mem , lv ) ) | |
! ( sortval = dm_pool_alloc ( mem , sizeof ( uint64_t ) ) ) ) {
log_error ( " Failed to allocate buffer for time. " ) ;
2012-01-19 19:34:32 +04:00
return 0 ;
}
* sortval = lv - > timestamp ;
dm_report_field_set_value ( field , repstr , sortval ) ;
return 1 ;
}
static int _lvhost_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
const struct logical_volume * lv = ( const struct logical_volume * ) data ;
char * repstr ;
2013-09-23 11:59:37 +04:00
if ( ! ( repstr = lv_host_dup ( mem , lv ) ) ) {
log_error ( " Failed to allocate buffer for host. " ) ;
return 0 ;
}
2012-01-19 19:34:32 +04:00
dm_report_field_set_value ( field , repstr , repstr ) ;
return 1 ;
}
2013-04-25 14:12:05 +04:00
static int _lvactive_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
char * repstr ;
2013-09-23 11:59:37 +04:00
if ( ! ( repstr = lv_active_dup ( mem , ( const struct logical_volume * ) data ) ) ) {
log_error ( " Failed to allocate buffer for active. " ) ;
return 0 ;
}
2013-04-25 14:12:05 +04:00
dm_report_field_set_value ( field , repstr , NULL ) ;
return 1 ;
}
2007-01-16 21:06:12 +03:00
/* Report object types */
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
/* necessary for displaying something for PVs not belonging to VG */
2009-01-10 20:09:40 +03:00
static struct format_instance _dummy_fid = {
2010-06-29 00:32:44 +04:00
. metadata_areas_in_use = { & ( _dummy_fid . metadata_areas_in_use ) , & ( _dummy_fid . metadata_areas_in_use ) } ,
2010-06-29 00:33:22 +04:00
. metadata_areas_ignored = { & ( _dummy_fid . metadata_areas_ignored ) , & ( _dummy_fid . metadata_areas_ignored ) } ,
2009-01-10 20:09:40 +03:00
} ;
2007-01-16 21:06:12 +03:00
static struct volume_group _dummy_vg = {
2009-01-10 20:09:40 +03:00
. fid = & _dummy_fid ,
2011-02-18 17:47:28 +03:00
. name = " " ,
2009-01-10 20:09:40 +03:00
. system_id = ( char * ) " " ,
. pvs = { & ( _dummy_vg . pvs ) , & ( _dummy_vg . pvs ) } ,
. lvs = { & ( _dummy_vg . lvs ) , & ( _dummy_vg . lvs ) } ,
. tags = { & ( _dummy_vg . tags ) , & ( _dummy_vg . tags ) } ,
2002-12-12 23:55:49 +03:00
} ;
2007-01-16 21:06:12 +03:00
static void * _obj_get_vg ( void * obj )
2006-10-02 20:46:27 +04:00
{
2007-01-16 21:06:12 +03:00
struct volume_group * vg = ( ( struct lvm_report_object * ) obj ) - > vg ;
2006-10-02 20:46:27 +04:00
2007-01-16 21:06:12 +03:00
return vg ? vg : & _dummy_vg ;
2006-10-02 20:46:27 +04:00
}
2007-01-16 21:06:12 +03:00
static void * _obj_get_lv ( void * obj )
2002-12-12 23:55:49 +03:00
{
2007-01-16 21:06:12 +03:00
return ( ( struct lvm_report_object * ) obj ) - > lv ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static void * _obj_get_pv ( void * obj )
2002-12-12 23:55:49 +03:00
{
2007-01-16 21:06:12 +03:00
return ( ( struct lvm_report_object * ) obj ) - > pv ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static void * _obj_get_seg ( void * obj )
2002-12-12 23:55:49 +03:00
{
2007-01-16 21:06:12 +03:00
return ( ( struct lvm_report_object * ) obj ) - > seg ;
2002-12-12 23:55:49 +03:00
}
2007-01-16 21:06:12 +03:00
static void * _obj_get_pvseg ( void * obj )
2002-12-12 23:55:49 +03:00
{
2007-01-16 21:06:12 +03:00
return ( ( struct lvm_report_object * ) obj ) - > pvseg ;
2002-12-12 23:55:49 +03:00
}
2013-09-18 04:09:15 +04:00
static void * _obj_get_devtypes ( void * obj )
{
return obj ;
}
2007-01-16 21:06:12 +03:00
static const struct dm_report_object_type _report_types [ ] = {
{ VGS , " Volume Group " , " vg_ " , _obj_get_vg } ,
{ LVS , " Logical Volume " , " lv_ " , _obj_get_lv } ,
{ PVS , " Physical Volume " , " pv_ " , _obj_get_pv } ,
2009-02-09 12:45:49 +03:00
{ LABEL , " Physical Volume Label " , " pv_ " , _obj_get_pv } ,
2007-01-16 21:06:12 +03:00
{ SEGS , " Logical Volume Segment " , " seg_ " , _obj_get_seg } ,
{ PVSEGS , " Physical Volume Segment " , " pvseg_ " , _obj_get_pvseg } ,
{ 0 , " " , " " , NULL } ,
} ;
2002-12-12 23:55:49 +03:00
2013-09-18 04:09:15 +04:00
static const struct dm_report_object_type _devtypes_report_types [ ] = {
{ DEVTYPES , " Device Types " , " devtype_ " , _obj_get_devtypes } ,
{ 0 , " " , " " , NULL } ,
} ;
2007-01-16 21:06:12 +03:00
/*
* Import column definitions
*/
2002-12-12 23:55:49 +03:00
2007-01-18 20:48:29 +03:00
# define STR DM_REPORT_FIELD_TYPE_STRING
# define NUM DM_REPORT_FIELD_TYPE_NUMBER
2010-08-20 16:44:03 +04:00
# define FIELD(type, strct, sorttype, head, field, width, func, id, desc, writeable) \
2010-01-07 17:37:11 +03:00
{ type , sorttype , offsetof ( type_ # # strct , field ) , width , \
2010-08-20 16:44:17 +04:00
# id, head, &_ ## func ## _disp, desc},
2010-01-07 17:37:11 +03:00
typedef struct physical_volume type_pv ;
typedef struct logical_volume type_lv ;
typedef struct volume_group type_vg ;
typedef struct lv_segment type_seg ;
typedef struct pv_segment type_pvseg ;
2002-12-12 23:55:49 +03:00
2013-09-18 04:09:15 +04:00
typedef dev_known_type_t type_devtype ;
2010-01-07 17:37:11 +03:00
static const struct dm_report_field_type _fields [ ] = {
2007-01-16 21:06:12 +03:00
# include "columns.h"
2007-01-30 02:01:18 +03:00
{ 0 , 0 , 0 , 0 , " " , " " , NULL , NULL } ,
2007-01-16 21:06:12 +03:00
} ;
2002-12-12 23:55:49 +03:00
2013-09-18 04:09:15 +04:00
static const struct dm_report_field_type _devtypes_fields [ ] = {
# include "columns-devtypes.h"
{ 0 , 0 , 0 , 0 , " " , " " , NULL , NULL } ,
} ;
2007-01-16 21:06:12 +03:00
# undef STR
# undef NUM
# undef FIELD
void * report_init ( struct cmd_context * cmd , const char * format , const char * keys ,
2007-07-10 22:20:00 +04:00
report_type_t * report_type , const char * separator ,
2008-06-25 01:21:04 +04:00
int aligned , int buffered , int headings , int field_prefixes ,
2008-06-25 02:48:53 +04:00
int quoted , int columns_as_rows )
2007-01-16 21:06:12 +03:00
{
uint32_t report_flags = 0 ;
2013-09-18 04:09:15 +04:00
int devtypes_report = * report_type & DEVTYPES ? 1 : 0 ;
2008-04-20 04:15:08 +04:00
void * rh ;
2002-12-12 23:55:49 +03:00
if ( aligned )
2007-01-16 21:06:12 +03:00
report_flags | = DM_REPORT_OUTPUT_ALIGNED ;
2002-12-12 23:55:49 +03:00
if ( buffered )
2007-01-16 21:06:12 +03:00
report_flags | = DM_REPORT_OUTPUT_BUFFERED ;
2002-12-12 23:55:49 +03:00
if ( headings )
2007-01-16 21:06:12 +03:00
report_flags | = DM_REPORT_OUTPUT_HEADINGS ;
2002-12-12 23:55:49 +03:00
2008-06-06 23:28:35 +04:00
if ( field_prefixes )
report_flags | = DM_REPORT_OUTPUT_FIELD_NAME_PREFIX ;
2008-06-25 01:21:04 +04:00
if ( ! quoted )
report_flags | = DM_REPORT_OUTPUT_FIELD_UNQUOTED ;
2008-06-25 02:48:53 +04:00
if ( columns_as_rows )
report_flags | = DM_REPORT_OUTPUT_COLUMNS_AS_ROWS ;
2013-09-18 04:09:15 +04:00
rh = dm_report_init ( report_type , devtypes_report ? _devtypes_report_types : _report_types ,
devtypes_report ? _devtypes_fields : _fields , format ,
2008-04-20 04:15:08 +04:00
separator , report_flags , keys , cmd ) ;
2008-12-15 16:30:45 +03:00
if ( rh & & field_prefixes )
2008-06-06 23:28:35 +04:00
dm_report_set_output_field_name_prefix ( rh , " lvm2_ " ) ;
2008-04-20 04:15:08 +04:00
return rh ;
2002-12-12 23:55:49 +03:00
}
/*
* Create a row of data for an object
*/
int report_object ( void * handle , struct volume_group * vg ,
struct logical_volume * lv , struct physical_volume * pv ,
2005-04-20 00:58:25 +04:00
struct lv_segment * seg , struct pv_segment * pvseg )
2002-12-12 23:55:49 +03:00
{
2007-01-16 21:06:12 +03:00
struct lvm_report_object obj ;
2002-12-12 23:55:49 +03:00
2009-01-10 20:09:40 +03:00
/* The two format fields might as well match. */
if ( ! vg & & pv )
_dummy_fid . fmt = pv - > fmt ;
2007-01-16 21:06:12 +03:00
obj . vg = vg ;
obj . lv = lv ;
obj . pv = pv ;
obj . seg = seg ;
obj . pvseg = pvseg ;
2004-05-05 22:23:11 +04:00
2007-01-16 21:06:12 +03:00
return dm_report_object ( handle , & obj ) ;
2002-12-12 23:55:49 +03:00
}
2013-09-18 04:09:15 +04:00
static int _report_devtype_single ( void * handle , const dev_known_type_t * devtype )
{
return dm_report_object ( handle , ( void * ) devtype ) ;
}
int report_devtypes ( void * handle )
{
int devtypeind = 0 ;
while ( _dev_known_types [ devtypeind ] . name [ 0 ] )
if ( ! _report_devtype_single ( handle , & _dev_known_types [ devtypeind + + ] ) )
return 0 ;
return 1 ;
}