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 .
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 "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"
2006-10-03 21:55:20 +04:00
# include "str_list.h"
2007-01-16 21:06:12 +03:00
# include "lvmcache.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 ;
} ;
2004-05-19 02:12:53 +04:00
static char _alloc_policy_char ( alloc_policy_t alloc )
{
switch ( alloc ) {
case ALLOC_CONTIGUOUS :
return ' c ' ;
2006-10-08 16:01:13 +04:00
case ALLOC_CLING :
2007-03-27 17:35:33 +04:00
return ' l ' ;
2004-05-19 02:12:53 +04:00
case ALLOC_NORMAL :
return ' n ' ;
case ALLOC_ANYWHERE :
return ' a ' ;
default :
return ' i ' ;
}
}
2010-02-15 23:27:33 +03:00
static const uint64_t _minusone64 = UINT64_C ( - 1 ) ;
static const int32_t _minusone32 = INT32_C ( - 1 ) ;
2007-11-09 19:51:54 +03:00
2002-12-12 23:55:49 +03:00
/*
* Data - munging functions to prepare each data type for display and sorting
*/
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +04:00
const void * data , void * private __attribute ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field , ( const char * * ) data ) ;
2002-12-12 23:55:49 +03:00
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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
}
2007-12-15 00:53:02 +03:00
static int _format_pvsegs ( struct dm_pool * mem , struct dm_report_field * field ,
const void * data , int range_format )
2004-05-05 14:58:44 +04:00
{
const struct lv_segment * seg = ( const struct lv_segment * ) data ;
unsigned int s ;
2005-10-17 03:03:59 +04:00
const char * name = NULL ;
uint32_t extent = 0 ;
2004-05-05 14:58:44 +04:00
char extent_str [ 32 ] ;
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_begin_object ( mem , 256 ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_begin_object failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
for ( s = 0 ; s < seg - > area_count ; s + + ) {
2005-06-01 20:51:55 +04:00
switch ( seg_type ( seg , s ) ) {
2004-05-05 14:58:44 +04:00
case AREA_LV :
2005-06-01 20:51:55 +04:00
name = seg_lv ( seg , s ) - > name ;
extent = seg_le ( seg , s ) ;
2004-05-05 14:58:44 +04:00
break ;
case AREA_PV :
2005-06-01 20:51:55 +04:00
name = dev_name ( seg_dev ( seg , s ) ) ;
extent = seg_pe ( seg , s ) ;
2004-05-05 14:58:44 +04:00
break ;
2005-06-14 21:54:48 +04:00
case AREA_UNASSIGNED :
name = " unassigned " ;
2004-05-05 14:58:44 +04:00
extent = 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_grow_object ( mem , name , strlen ( name ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
2007-12-15 00:53:02 +03:00
if ( dm_snprintf ( extent_str , sizeof ( extent_str ) ,
2008-01-30 17:00:02 +03:00
" %s% " PRIu32 " %s " ,
2007-12-15 00:53:02 +03:00
range_format ? " : " : " ( " , extent ,
range_format ? " - " : " ) " ) < 0 ) {
2006-08-21 16:54:53 +04:00
log_error ( " Extent number dm_snprintf failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_grow_object ( mem , extent_str , strlen ( extent_str ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
2007-12-15 00:53:02 +03:00
if ( range_format ) {
if ( dm_snprintf ( extent_str , sizeof ( extent_str ) ,
2008-01-30 17:00:02 +03:00
" % " PRIu32 , extent + seg - > area_len - 1 ) < 0 ) {
2007-12-15 00:53:02 +03:00
log_error ( " Extent number dm_snprintf failed " ) ;
return 0 ;
}
if ( ! dm_pool_grow_object ( mem , extent_str , strlen ( extent_str ) ) ) {
log_error ( " dm_pool_grow_object failed " ) ;
return 0 ;
}
}
2004-05-05 14:58:44 +04:00
if ( ( s ! = seg - > area_count - 1 ) & &
2007-12-15 00:53:02 +03:00
! dm_pool_grow_object ( mem , range_format ? " " : " , " , 1 ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
}
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_grow_object ( mem , " \0 " , 1 ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-05-05 14:58:44 +04:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , dm_pool_end_object ( mem ) , NULL ) ;
2004-05-05 14:58:44 +04:00
return 1 ;
}
2006-10-03 21:55:20 +04:00
2007-12-15 00:53:02 +03: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 ) ) )
{
return _format_pvsegs ( mem , field , data , 0 ) ;
}
static int _peranges_disp ( struct dm_report * rh __attribute ( ( unused ) ) , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private __attribute ( ( unused ) ) )
{
return _format_pvsegs ( mem , field , data , 1 ) ;
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
2004-03-08 20:19:15 +03:00
struct str_list * sl ;
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_begin_object ( mem , 256 ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_begin_object failed " ) ;
2004-03-08 20:19:15 +03:00
return 0 ;
}
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( sl , tags ) {
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_grow_object ( mem , sl - > str , strlen ( sl - > str ) ) | |
( sl - > list . n ! = tags & & ! dm_pool_grow_object ( mem , " , " , 1 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-03-08 20:19:15 +03:00
return 0 ;
}
}
2007-01-16 21:06:12 +03:00
if ( ! dm_pool_grow_object ( mem , " \0 " , 1 ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_grow_object failed " ) ;
2004-03-08 20:19:15 +03:00
return 0 ;
}
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , dm_pool_end_object ( mem ) , 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 ;
2008-11-04 01:14:30 +03:00
struct dm_list * modules ;
2006-10-03 21:55:20 +04:00
2007-01-16 21:06:12 +03:00
if ( ! ( modules = str_list_create ( mem ) ) ) {
2006-10-03 21:55:20 +04:00
log_error ( " modules str_list allocation failed " ) ;
return 0 ;
}
2007-01-16 21:06:12 +03:00
if ( ! list_lv_modules ( mem , lv , modules ) )
2006-10-03 21:55:20 +04:00
return_0 ;
2007-01-16 21:06:12 +03:00
return _tags_disp ( rh , mem , field , modules , private ) ;
2006-10-03 21:55:20 +04:00
}
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
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
struct lvinfo info ;
2007-11-12 23:51:54 +03:00
if ( lv_info ( lv - > vg - > cmd , lv , & info , 0 , 0 ) & & info . exists )
2007-01-22 18:07:21 +03:00
return dm_report_field_int ( rh , field , & info . 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
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
struct lvinfo info ;
2007-11-12 23:51:54 +03:00
if ( lv_info ( lv - > vg - > cmd , lv , & info , 0 , 0 ) & & info . exists )
2007-01-22 18:07:21 +03:00
return dm_report_field_int ( rh , field , & info . 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
}
2008-01-10 21:35:51 +03:00
static int _lv_mimage_in_sync ( const struct logical_volume * lv )
2007-12-22 05:13:00 +03:00
{
float percent ;
2009-10-01 04:35:29 +04:00
percent_range_t percent_range ;
2008-01-16 22:00:59 +03:00
struct lv_segment * mirror_seg = find_mirror_seg ( first_seg ( lv ) ) ;
2007-12-22 05:13:00 +03:00
2008-01-16 22:00:59 +03:00
if ( ! ( lv - > status & MIRROR_IMAGE ) | | ! mirror_seg )
2007-12-22 05:13:00 +03:00
return_0 ;
2009-10-01 04:35:29 +04:00
if ( ! lv_mirror_percent ( lv - > vg - > cmd , mirror_seg - > lv , 0 , & percent ,
& percent_range , NULL ) )
2007-12-22 05:13:00 +03:00
return_0 ;
2009-10-01 04:35:29 +04:00
return ( percent_range = = PERCENT_100 ) ? 1 : 0 ;
2007-12-22 05:13:00 +03:00
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
2003-01-09 01:44:07 +03:00
struct lvinfo info ;
2002-12-20 02:25:55 +03:00
char * repstr ;
2003-01-21 21:50:50 +03:00
float snap_percent ;
2009-10-01 04:35:29 +04:00
percent_range_t percent_range ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_zalloc ( mem , 7 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2008-06-25 20:52:27 +04:00
/* Blank if this is a "free space" LV. */
if ( ! * lv - > name )
goto out ;
2003-05-06 16:06:02 +04:00
if ( lv - > status & PVMOVE )
repstr [ 0 ] = ' p ' ;
2008-01-10 21:35:51 +03:00
else if ( lv - > status & CONVERTING )
repstr [ 0 ] = ' c ' ;
2009-10-26 13:01:56 +03:00
else if ( lv - > status & VIRTUAL )
repstr [ 0 ] = ' v ' ;
/* Origin takes precedence over Mirror */
2010-01-13 04:48:38 +03:00
else if ( lv_is_origin ( lv ) ) {
2010-01-13 04:55:43 +03:00
if ( lv_is_merging_origin ( lv ) )
2010-01-13 04:48:38 +03:00
repstr [ 0 ] = ' O ' ;
else
repstr [ 0 ] = ' o ' ;
}
2006-05-12 00:17:17 +04:00
else if ( lv - > status & MIRRORED ) {
if ( lv - > status & MIRROR_NOTSYNCED )
repstr [ 0 ] = ' M ' ;
else
repstr [ 0 ] = ' m ' ;
} else if ( lv - > status & MIRROR_IMAGE )
2007-12-22 05:13:00 +03:00
if ( _lv_mimage_in_sync ( lv ) )
repstr [ 0 ] = ' i ' ;
else
repstr [ 0 ] = ' I ' ;
2005-06-01 20:51:55 +04:00
else if ( lv - > status & MIRROR_LOG )
repstr [ 0 ] = ' l ' ;
2010-01-13 04:48:38 +03:00
else if ( lv_is_cow ( lv ) ) {
2010-01-13 04:55:43 +03:00
if ( lv_is_merging_cow ( lv ) )
2010-01-13 04:48:38 +03:00
repstr [ 0 ] = ' S ' ;
else
repstr [ 0 ] = ' s ' ;
} else
2002-12-20 02:25:55 +03:00
repstr [ 0 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2003-05-06 16:06:02 +04:00
if ( lv - > status & PVMOVE )
repstr [ 1 ] = ' - ' ;
else if ( lv - > status & LVM_WRITE )
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' w ' ;
2008-06-25 20:52:27 +04:00
else if ( lv - > status & LVM_READ )
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' r ' ;
2008-06-25 20:52:27 +04:00
else
repstr [ 1 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2004-05-19 02:12:53 +04:00
repstr [ 2 ] = _alloc_policy_char ( lv - > alloc ) ;
2002-12-12 23:55:49 +03:00
2003-05-06 16:06:02 +04:00
if ( lv - > status & LOCKED )
repstr [ 2 ] = toupper ( repstr [ 2 ] ) ;
2002-12-12 23:55:49 +03:00
if ( lv - > status & FIXED_MINOR )
2002-12-20 02:25:55 +03:00
repstr [ 3 ] = ' m ' ; /* Fixed Minor */
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 3 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2007-11-12 23:51:54 +03:00
if ( lv_info ( lv - > vg - > cmd , lv , & info , 1 , 0 ) & & info . exists ) {
2002-12-12 23:55:49 +03:00
if ( info . suspended )
2002-12-20 02:25:55 +03:00
repstr [ 4 ] = ' s ' ; /* Suspended */
2005-11-09 01:52:26 +03:00
else if ( info . live_table )
2002-12-20 02:25:55 +03:00
repstr [ 4 ] = ' a ' ; /* Active */
2005-11-09 01:52:26 +03:00
else if ( info . inactive_table )
repstr [ 4 ] = ' i ' ; /* Inactive with table */
2002-12-12 23:55:49 +03:00
else
2005-11-09 01:52:26 +03:00
repstr [ 4 ] = ' d ' ; /* Inactive without table */
2003-01-21 21:50:50 +03:00
/* Snapshot dropped? */
2006-04-06 17:39:16 +04:00
if ( info . live_table & & lv_is_cow ( lv ) & &
2009-10-01 04:35:29 +04:00
( ! lv_snapshot_percent ( lv , & snap_percent , & percent_range ) | |
percent_range = = PERCENT_INVALID ) ) {
2003-01-21 21:50:50 +03:00
repstr [ 0 ] = toupper ( repstr [ 0 ] ) ;
2003-07-05 02:34:56 +04:00
if ( info . suspended )
2005-11-09 01:52:26 +03:00
repstr [ 4 ] = ' S ' ; /* Susp Inv snapshot */
2003-07-05 02:34:56 +04:00
else
2005-11-09 01:52:26 +03:00
repstr [ 4 ] = ' I ' ; /* Invalid snapshot */
2003-07-05 02:34:56 +04:00
}
2003-01-21 21:50:50 +03:00
2005-11-09 01:52:26 +03:00
if ( info . open_count )
repstr [ 5 ] = ' o ' ; /* Open */
else
repstr [ 5 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
} else {
2002-12-20 02:25:55 +03:00
repstr [ 4 ] = ' - ' ;
repstr [ 5 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
}
2008-06-25 20:52:27 +04:00
out :
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-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 uint32_t status = * ( const uint32_t * ) data ;
char * repstr ;
2002-12-12 23:55:49 +03:00
2008-04-20 04:15:08 +04:00
if ( ! ( repstr = dm_pool_zalloc ( mem , 3 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
if ( status & ALLOCATABLE_PV )
2002-12-20 02:25:55 +03:00
repstr [ 0 ] = ' a ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 0 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
if ( status & EXPORTED_VG )
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' x ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' - ' ;
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-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_zalloc ( mem , 7 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2004-05-19 02:12:53 +04:00
if ( vg - > status & LVM_WRITE )
2002-12-20 02:25:55 +03:00
repstr [ 0 ] = ' w ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 0 ] = ' r ' ;
2002-12-12 23:55:49 +03:00
2009-09-15 22:35:13 +04:00
if ( vg_is_resizeable ( vg ) )
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' z ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 1 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2009-09-14 23:44:15 +04:00
if ( vg_is_exported ( vg ) )
2002-12-20 02:25:55 +03:00
repstr [ 2 ] = ' x ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 2 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2008-09-19 10:42:00 +04:00
if ( vg_missing_pv_count ( vg ) )
2002-12-20 02:25:55 +03:00
repstr [ 3 ] = ' p ' ;
2002-12-12 23:55:49 +03:00
else
2002-12-20 02:25:55 +03:00
repstr [ 3 ] = ' - ' ;
2002-12-12 23:55:49 +03:00
2004-05-19 02:12:53 +04:00
repstr [ 4 ] = _alloc_policy_char ( vg - > alloc ) ;
2008-04-10 21:09:32 +04:00
if ( vg_is_clustered ( vg ) )
2005-08-16 03:34:11 +04:00
repstr [ 5 ] = ' c ' ;
else
repstr [ 5 ] = ' - ' ;
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-01-16 21:06:12 +03:00
static int _segtype_disp ( struct dm_report * rh __attribute ( ( unused ) ) ,
2007-08-22 18:38:18 +04:00
struct dm_pool * mem __attribute ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2007-08-22 18:38:18 +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 ;
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
if ( seg - > area_count = = 1 ) {
dm_report_field_set_value ( field , " linear " , NULL ) ;
return 1 ;
}
2002-12-12 23:55:49 +03:00
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , seg - > segtype - > ops - > name ( seg ) , NULL ) ;
2002-12-12 23:55:49 +03:00
return 1 ;
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
struct lv_segment * seg ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( seg , & lv - > segments ) {
2005-06-01 20:51:55 +04:00
if ( ! seg_is_mirrored ( seg ) | | ! seg - > log_lv )
continue ;
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field ,
( const char * * ) & seg - > log_lv - > 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 ,
2007-08-22 18:38:18 +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 ;
2009-05-14 01:27:43 +04:00
if ( lv_is_visible ( lv ) ) {
2005-06-03 18:49:51 +04:00
repstr = lv - > name ;
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field , ( const char * * ) & repstr ) ;
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 ;
}
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 ) ;
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
struct lv_segment * seg ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( seg , & lv - > segments ) {
2003-05-06 16:06:02 +04:00
if ( ! ( seg - > status & PVMOVE ) )
continue ;
2005-06-01 20:51:55 +04:00
name = dev_name ( seg_dev ( seg , 0 ) ) ;
2007-01-22 18:07:21 +03:00
return dm_report_field_string ( rh , field , & name ) ;
2003-05-06 16:06:02 +04:00
}
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , NULL ) ;
2003-05-06 16:06:02 +04:00
return 1 ;
}
2008-01-10 21:35:51 +03:00
static int _convertlv_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 ;
const char * name = NULL ;
struct lv_segment * seg ;
if ( lv - > status & CONVERTING ) {
if ( lv - > status & MIRRORED ) {
seg = first_seg ( lv ) ;
/* Temporary mirror is always area_num == 0 */
if ( seg_type ( seg , 0 ) = = AREA_LV & &
is_temporary_mirror_layer ( seg_lv ( seg , 0 ) ) )
name = seg_lv ( seg , 0 ) - > name ;
}
}
if ( name )
return dm_report_field_string ( rh , field , & name ) ;
dm_report_field_set_value ( field , " " , NULL ) ;
return 1 ;
}
2007-08-22 18:38:18 +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 ;
}
2002-12-20 02:25:55 +03:00
* sortval = ( const 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 ;
}
2007-08-22 18:38:18 +04:00
static int _size64_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 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 ;
}
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 ,
const void * data , void * private __attribute ( ( unused ) ) )
{
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 ;
struct lvinfo info ;
2007-11-14 03:08:25 +03:00
if ( ! lv_info ( lv - > vg - > cmd , lv , & info , 0 , 1 ) | | ! info . exists )
2010-02-15 23:27:33 +03:00
return dm_report_field_int32 ( rh , field , & _minusone32 ) ;
2007-11-12 23:51:54 +03:00
2007-11-14 03:08:25 +03:00
return _size32_disp ( rh , mem , field , & info . 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 ;
2002-12-12 23:55:49 +03:00
uint64_t size ;
2009-07-26 16:41:09 +04:00
size = ( uint64_t ) 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
}
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 ;
2002-12-12 23:55:49 +03:00
uint64_t start ;
2005-02-01 19:19:48 +03:00
start = ( uint64_t ) seg - > le * seg - > lv - > vg - > extent_size ;
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 ,
struct dm_pool * mem __attribute ( ( unused ) ) ,
struct dm_report_field * field ,
const void * data ,
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 ;
2002-12-12 23:55:49 +03:00
uint64_t size ;
2005-02-01 19:19:48 +03:00
size = ( uint64_t ) seg - > len * seg - > lv - > vg - > extent_size ;
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 _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 ;
uint64_t size ;
2006-04-06 17:39:16 +04:00
if ( lv_is_cow ( seg - > lv ) )
size = ( uint64_t ) find_cow ( seg - > lv ) - > chunk_size ;
2005-09-23 21:06:01 +04:00
else
2009-04-25 05:17:59 +04:00
size = UINT64_C ( 0 ) ;
return _size64_disp ( rh , mem , field , & size , private ) ;
}
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 ;
uint64_t size ;
if ( lv_is_cow ( lv ) )
size = ( uint64_t ) find_cow ( lv ) - > len * lv - > vg - > extent_size ;
else if ( lv_is_origin ( lv ) )
size = lv - > size ;
else
size = UINT64_C ( 0 ) ;
2005-09-23 21:06:01 +04:00
2007-01-16 21:06:12 +03:00
return _size64_disp ( rh , mem , field , & size , private ) ;
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 ;
2002-12-12 23:55:49 +03:00
uint64_t used ;
if ( ! pv - > pe_count )
used = 0LL ;
else
2005-02-01 19:19:48 +03:00
used = ( uint64_t ) pv - > pe_alloc_count * pv - > pe_size ;
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 ;
uint64_t freespace ;
2002-12-12 23:55:49 +03:00
2010-02-14 06:21:37 +03:00
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 ;
2002-12-12 23:55:49 +03:00
uint64_t size ;
2010-02-14 06:21:37 +03:00
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 ;
2004-08-11 17:15:05 +04:00
uint64_t size ;
2010-02-14 06:21:37 +03:00
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 ;
uint64_t freespace ;
2002-12-12 23:55:49 +03:00
2009-07-26 16:41:09 +04:00
freespace = ( uint64_t ) 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
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
2007-01-16 21:06:12 +03:00
if ( ! ( repstr = dm_pool_alloc ( mem , 40 ) ) ) {
2005-10-17 03:03:59 +04:00
log_error ( " dm_pool_alloc failed " ) ;
2002-12-12 23:55:49 +03:00
return 0 ;
}
2008-01-30 16:19:47 +03:00
if ( ! id_write_format ( ( const struct id * ) data , repstr , 40 ) )
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-08-22 18:38:18 +04:00
static int _uint32_disp ( struct dm_report * rh , struct dm_pool * mem __attribute ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2007-08-22 18:38:18 +04:00
const void * data , void * private __attribute ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2007-01-22 18:07:21 +03:00
return dm_report_field_uint32 ( rh , field , data ) ;
2002-12-12 23:55:49 +03:00
}
2007-08-22 18:38:18 +04:00
static int _int32_disp ( struct dm_report * rh , struct dm_pool * mem __attribute ( ( unused ) ) ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2007-08-22 18:38:18 +04:00
const void * data , void * private __attribute ( ( unused ) ) )
2002-12-12 23:55:49 +03:00
{
2007-01-22 18:07:21 +03:00
return dm_report_field_int32 ( rh , field , data ) ;
2002-12-12 23:55:49 +03:00
}
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 )
{
2007-07-10 22:20:00 +04:00
uint32_t count ;
2009-07-26 16:41:09 +04:00
const struct physical_volume * pv =
( const struct physical_volume * ) data ;
2007-07-09 19:40:43 +04:00
2009-07-26 16:41:09 +04:00
count = pv_mda_count ( pv ) ;
2007-07-09 19:40:43 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
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 ;
uint32_t count ;
2009-10-31 20:26:13 +03:00
count = vg_mda_count ( vg ) ;
2007-07-09 19:40:43 +04:00
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
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 )
{
2008-01-30 17:00:02 +03:00
struct lvmcache_info * info ;
2007-11-05 20:17:55 +03:00
uint64_t freespace = UINT64_MAX , mda_free ;
2010-02-15 21:34:00 +03:00
const char * pvid = ( const char * ) ( & ( ( const struct id * ) data ) - > uuid ) ;
2007-11-05 20:17:55 +03:00
struct metadata_area * mda ;
2009-02-06 15:41:51 +03:00
if ( ( info = info_from_pvid ( pvid , 0 ) ) )
dm_list_iterate_items ( mda , & info - > mdas ) {
if ( ! mda - > ops - > mda_free_sectors )
continue ;
mda_free = mda - > ops - > mda_free_sectors ( mda ) ;
if ( mda_free < freespace )
freespace = mda_free ;
}
2007-11-05 20:17:55 +03:00
if ( freespace = = UINT64_MAX )
freespace = UINT64_C ( 0 ) ;
return _size64_disp ( rh , mem , field , & freespace , private ) ;
}
2009-01-10 01:44:33 +03:00
static uint64_t _find_min_mda_size ( struct dm_list * mdas )
{
uint64_t min_mda_size = UINT64_MAX , mda_size ;
struct metadata_area * mda ;
dm_list_iterate_items ( mda , mdas ) {
if ( ! mda - > ops - > mda_total_sectors )
continue ;
mda_size = mda - > ops - > mda_total_sectors ( mda ) ;
if ( mda_size < min_mda_size )
min_mda_size = mda_size ;
}
if ( min_mda_size = = UINT64_MAX )
min_mda_size = UINT64_C ( 0 ) ;
return min_mda_size ;
}
static int _pvmdasize_disp ( struct dm_report * rh , struct dm_pool * mem ,
struct dm_report_field * field ,
const void * data , void * private )
{
struct lvmcache_info * info ;
2009-02-06 15:41:51 +03:00
uint64_t min_mda_size = 0 ;
2010-02-15 21:34:00 +03:00
const char * pvid = ( const char * ) ( & ( ( const struct id * ) data ) - > uuid ) ;
2009-01-10 01:44:33 +03:00
/* PVs could have 2 mdas of different sizes (rounding effect) */
2009-02-06 15:41:51 +03:00
if ( ( info = info_from_pvid ( pvid , 0 ) ) )
min_mda_size = _find_min_mda_size ( & info - > mdas ) ;
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 ;
uint64_t min_mda_size ;
2009-01-10 20:09:40 +03:00
min_mda_size = _find_min_mda_size ( & vg - > fid - > metadata_areas ) ;
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 ;
uint64_t freespace = UINT64_MAX , mda_free ;
struct metadata_area * mda ;
2008-11-04 01:14:30 +03:00
dm_list_iterate_items ( mda , & vg - > fid - > metadata_areas ) {
2007-11-05 20:17:55 +03:00
if ( ! mda - > ops - > mda_free_sectors )
continue ;
mda_free = mda - > ops - > mda_free_sectors ( mda ) ;
if ( mda_free < freespace )
freespace = mda_free ;
}
2009-01-10 20:09:40 +03:00
2007-11-05 20:17:55 +03:00
if ( freespace = = UINT64_MAX )
freespace = UINT64_C ( 0 ) ;
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 ;
2008-12-04 18:54:26 +03:00
uint32_t count ;
2008-04-10 21:19:02 +04:00
2009-05-14 01:27:43 +04:00
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 ;
2002-12-12 23:55:49 +03:00
uint32_t count ;
2008-11-04 01:14:30 +03:00
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 ;
uint32_t count ;
count = snapshot_count ( vg ) ;
return _uint32_disp ( rh , mem , field , & count , private ) ;
}
2007-08-22 18:38:18 +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 ,
2007-08-22 18:38:18 +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 ;
2003-07-05 02:34:56 +04:00
struct lvinfo info ;
2002-12-12 23:55:49 +03:00
float snap_percent ;
2009-10-01 04:35:29 +04:00
percent_range_t percent_range ;
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 ) ) | |
2010-05-21 02:24:33 +04:00
! lv_info ( lv - > vg - > cmd , lv , & info , 0 , 0 ) | | ! info . exists ) {
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 ;
}
2009-10-01 04:35:29 +04:00
if ( ! lv_snapshot_percent ( lv , & snap_percent , & percent_range ) | |
( percent_range = = PERCENT_INVALID ) ) {
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 ;
}
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( repstr , 7 , " %.2f " , 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 ;
}
2009-10-01 05:04:27 +04:00
static int _copypercent_disp ( struct dm_report * rh __attribute ( ( unused ) ) ,
struct dm_pool * mem ,
2007-01-16 21:06:12 +03:00
struct dm_report_field * field ,
2007-08-22 18:38:18 +04:00
const void * data , void * private __attribute ( ( unused ) ) )
2003-05-06 16:06:02 +04:00
{
struct logical_volume * lv = ( struct logical_volume * ) data ;
2004-05-05 14:58:44 +04:00
float percent ;
2009-10-01 04:35:29 +04:00
percent_range_t percent_range ;
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 ;
}
2004-05-05 22:23:11 +04:00
if ( ( ! ( lv - > status & PVMOVE ) & & ! ( lv - > status & MIRRORED ) ) | |
2009-10-01 04:35:29 +04:00
! lv_mirror_percent ( lv - > vg - > cmd , lv , 0 , & percent , & percent_range ,
NULL ) | | ( percent_range = = PERCENT_INVALID ) ) {
2003-05-06 16:06:02 +04:00
* sortval = UINT64_C ( 0 ) ;
2007-01-16 21:06:12 +03:00
dm_report_field_set_value ( field , " " , sortval ) ;
2003-05-06 16:06:02 +04:00
return 1 ;
}
2009-10-01 05:04:27 +04:00
percent = copy_percent ( lv , & percent_range ) ;
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 ;
}
2006-08-21 16:54:53 +04:00
if ( dm_snprintf ( repstr , 7 , " %.2f " , 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 ;
}
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 = {
. metadata_areas = { & ( _dummy_fid . metadata_areas ) , & ( _dummy_fid . metadata_areas ) } ,
} ;
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 ,
2008-02-06 18:47:28 +03:00
. name = ( char * ) " " ,
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
}
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
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-01-07 17:37:11 +03:00
# define FIELD(type, strct, sorttype, head, field, width, func, id, desc) \
{ type , sorttype , offsetof ( type_ # # strct , field ) , width , \
id , head , & _ # # func # # _disp , desc } ,
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
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
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 ;
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 ;
2008-04-20 04:15:08 +04:00
rh = dm_report_init ( report_type , _report_types , _fields , format ,
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
}