2010-08-20 16:44:58 +04:00
/*
2012-01-19 19:34:32 +04:00
* Copyright ( C ) 2010 - 2012 Red Hat , Inc . All rights reserved .
2010-08-20 16:44:58 +04:00
*
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v .2 .1 .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <errno.h>
# include "libdevmapper.h"
# include "properties.h"
2010-12-15 02:20:58 +03:00
# include "activate.h"
2010-08-20 16:44:58 +04:00
# include "lvm-logging.h"
# include "lvm-types.h"
# include "metadata.h"
2010-09-30 18:08:46 +04:00
# define GET_NUM_PROPERTY_FN(NAME, VALUE, TYPE, VAR) \
2010-09-30 18:09:45 +04:00
static int _ # # NAME # # _get ( const void * obj , struct lvm_property_type * prop ) \
2010-08-20 17:02:39 +04:00
{ \
2010-09-30 18:09:45 +04:00
const struct TYPE * VAR = ( const struct TYPE * ) obj ; \
2010-08-20 17:02:39 +04:00
\
2010-10-21 18:49:43 +04:00
prop - > value . integer = VALUE ; \
2010-08-20 17:02:39 +04:00
return 1 ; \
}
2010-09-30 18:08:46 +04:00
# define GET_VG_NUM_PROPERTY_FN(NAME, VALUE) \
GET_NUM_PROPERTY_FN ( NAME , VALUE , volume_group , vg )
# define GET_PV_NUM_PROPERTY_FN(NAME, VALUE) \
GET_NUM_PROPERTY_FN ( NAME , VALUE , physical_volume , pv )
# define GET_LV_NUM_PROPERTY_FN(NAME, VALUE) \
GET_NUM_PROPERTY_FN ( NAME , VALUE , logical_volume , lv )
2010-11-17 23:08:14 +03:00
# define GET_LVSEG_NUM_PROPERTY_FN(NAME, VALUE) \
GET_NUM_PROPERTY_FN ( NAME , VALUE , lv_segment , lvseg )
2010-11-17 23:11:27 +03:00
# define GET_PVSEG_NUM_PROPERTY_FN(NAME, VALUE) \
GET_NUM_PROPERTY_FN ( NAME , VALUE , pv_segment , pvseg )
2010-09-30 18:08:46 +04:00
2010-11-17 22:15:10 +03:00
# define SET_NUM_PROPERTY_FN(NAME, SETFN, TYPE, VAR) \
static int _ # # NAME # # _set ( void * obj , struct lvm_property_type * prop ) \
{ \
struct TYPE * VAR = ( struct TYPE * ) obj ; \
\
SETFN ( VAR , prop - > value . integer ) ; \
return 1 ; \
}
# define SET_VG_NUM_PROPERTY_FN(NAME, SETFN) \
SET_NUM_PROPERTY_FN ( NAME , SETFN , volume_group , vg )
# define SET_PV_NUM_PROPERTY_FN(NAME, SETFN) \
SET_NUM_PROPERTY_FN ( NAME , SETFN , physical_volume , pv )
# define SET_LV_NUM_PROPERTY_FN(NAME, SETFN) \
SET_NUM_PROPERTY_FN ( NAME , SETFN , logical_volume , lv )
2010-09-30 18:08:46 +04:00
# define GET_STR_PROPERTY_FN(NAME, VALUE, TYPE, VAR) \
2010-09-30 18:09:45 +04:00
static int _ # # NAME # # _get ( const void * obj , struct lvm_property_type * prop ) \
2010-09-30 18:08:46 +04:00
{ \
2010-09-30 18:09:45 +04:00
const struct TYPE * VAR = ( const struct TYPE * ) obj ; \
2010-09-30 18:08:46 +04:00
\
2010-10-21 18:49:43 +04:00
prop - > value . string = ( char * ) VALUE ; \
2010-09-30 18:08:46 +04:00
return 1 ; \
}
# define GET_VG_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN ( NAME , VALUE , volume_group , vg )
# define GET_PV_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN ( NAME , VALUE , physical_volume , pv )
# define GET_LV_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN ( NAME , VALUE , logical_volume , lv )
2010-11-17 23:08:14 +03:00
# define GET_LVSEG_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN ( NAME , VALUE , lv_segment , lvseg )
2010-11-17 23:11:27 +03:00
# define GET_PVSEG_STR_PROPERTY_FN(NAME, VALUE) \
GET_STR_PROPERTY_FN ( NAME , VALUE , pv_segment , pvseg )
2010-08-20 17:02:39 +04:00
2010-09-30 18:09:45 +04:00
static int _not_implemented_get ( const void * obj , struct lvm_property_type * prop )
{
log_errno ( ENOSYS , " Function not implemented " ) ;
2013-07-09 05:06:29 +04:00
2010-09-30 18:09:45 +04:00
return 0 ;
}
static int _not_implemented_set ( void * obj , struct lvm_property_type * prop )
2010-08-20 16:44:58 +04:00
{
log_errno ( ENOSYS , " Function not implemented " ) ;
2013-07-09 05:06:29 +04:00
2010-08-20 16:44:58 +04:00
return 0 ;
}
2013-07-09 05:06:29 +04:00
static percent_t _copy_percent ( const struct logical_volume * lv )
{
percent_t percent ;
if ( ! lv_mirror_percent ( lv - > vg - > cmd , lv , 0 , & percent , NULL ) )
percent = PERCENT_INVALID ;
return percent ;
2010-12-15 02:20:58 +03:00
}
2013-07-09 05:06:29 +04:00
static uint64_t _mismatches ( const struct logical_volume * lv )
{
2013-04-12 00:33:59 +04:00
uint64_t cnt ;
if ( ! lv_raid_mismatch_count ( lv , & cnt ) )
return 0 ;
return cnt ;
}
2013-07-09 05:06:29 +04:00
static char * _sync_action ( const struct logical_volume * lv )
{
2013-04-12 00:33:59 +04:00
char * action ;
if ( ! lv_raid_sync_action ( lv , & action ) )
return 0 ;
2013-07-09 05:06:29 +04:00
2013-04-12 00:33:59 +04:00
return action ;
}
2013-07-09 05:06:29 +04:00
static uint32_t _writebehind ( const struct logical_volume * lv )
{
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 first_seg ( lv ) - > writebehind ;
}
2013-07-09 05:06:29 +04:00
static uint32_t _minrecoveryrate ( const struct logical_volume * lv )
{
2013-05-31 20:25:52 +04:00
return first_seg ( lv ) - > min_recovery_rate ;
}
2013-07-09 05:06:29 +04:00
static uint32_t _maxrecoveryrate ( const struct logical_volume * lv )
{
2013-05-31 20:25:52 +04:00
return first_seg ( lv ) - > max_recovery_rate ;
}
2013-07-09 05:06:29 +04:00
static percent_t _snap_percent ( const struct logical_volume * lv )
{
percent_t percent ;
2012-10-08 14:06:30 +04:00
2013-07-09 05:06:29 +04:00
if ( ! lv_is_cow ( lv ) | | ! lv_snapshot_percent ( lv , & percent ) )
percent = PERCENT_INVALID ;
2012-10-08 14:06:30 +04:00
2013-07-09 05:06:29 +04:00
return percent ;
2010-12-15 02:20:58 +03:00
}
2012-01-19 19:34:32 +04:00
static percent_t _data_percent ( const struct logical_volume * lv )
{
2013-07-09 05:06:29 +04:00
percent_t percent ;
2012-01-19 19:34:32 +04:00
2012-10-05 11:56:50 +04:00
if ( lv_is_cow ( lv ) )
return _snap_percent ( lv ) ;
if ( lv_is_thin_volume ( lv ) )
2013-07-09 05:06:29 +04:00
return lv_thin_percent ( lv , 0 , & percent ) ? percent : PERCENT_INVALID ;
2012-10-05 11:56:50 +04:00
2013-07-09 05:06:29 +04:00
return lv_thin_pool_percent ( lv , 0 , & percent ) ? percent : PERCENT_INVALID ;
2012-01-19 19:34:32 +04:00
}
static percent_t _metadata_percent ( const struct logical_volume * lv )
{
2013-07-09 05:06:29 +04:00
percent_t percent ;
2012-01-19 19:34:32 +04:00
2013-07-09 05:06:29 +04:00
return lv_thin_pool_percent ( lv , 1 , & percent ) ? percent : PERCENT_INVALID ;
2012-01-19 19:34:32 +04:00
}
2010-08-20 16:44:58 +04:00
/* PV */
2010-09-30 18:09:33 +04:00
GET_PV_STR_PROPERTY_FN ( pv_fmt , pv_fmt_dup ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_fmt_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_STR_PROPERTY_FN ( pv_uuid , pv_uuid_dup ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_uuid_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( dev_size , SECTOR_SIZE * pv_dev_size ( pv ) )
2010-09-30 18:09:45 +04:00
# define _dev_size_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_STR_PROPERTY_FN ( pv_name , pv_name_dup ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_name_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_mda_free , SECTOR_SIZE * pv_mda_free ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_mda_free_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_mda_size , SECTOR_SIZE * pv_mda_size ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_mda_size_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pe_start , SECTOR_SIZE * pv - > pe_start )
2010-09-30 18:09:45 +04:00
# define _pe_start_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_size , SECTOR_SIZE * pv_size_field ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_size_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_free , SECTOR_SIZE * pv_free ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_free_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_used , SECTOR_SIZE * pv_used ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_used_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_STR_PROPERTY_FN ( pv_attr , pv_attr_dup ( pv - > vg - > vgmem , pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_attr_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_pe_count , pv - > pe_count )
2010-09-30 18:09:45 +04:00
# define _pv_pe_count_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_pe_alloc_count , pv - > pe_alloc_count )
2010-09-30 18:09:45 +04:00
# define _pv_pe_alloc_count_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_STR_PROPERTY_FN ( pv_tags , pv_tags_dup ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_tags_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_mda_count , pv_mda_count ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_mda_count_set _not_implemented_set
2010-09-30 18:09:33 +04:00
GET_PV_NUM_PROPERTY_FN ( pv_mda_used_count , pv_mda_used_count ( pv ) )
2010-09-30 18:09:45 +04:00
# define _pv_mda_used_count_set _not_implemented_set
2013-05-28 14:37:22 +04:00
GET_PV_NUM_PROPERTY_FN ( ba_start , SECTOR_SIZE * pv - > ba_start )
# define _ba_start_set _not_implemented_set
GET_PV_NUM_PROPERTY_FN ( ba_size , SECTOR_SIZE * pv - > ba_size )
# define _ba_size_set _not_implemented_set
2010-08-20 16:44:58 +04:00
/* LV */
2010-10-12 20:11:20 +04:00
GET_LV_STR_PROPERTY_FN ( lv_uuid , lv_uuid_dup ( lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_uuid_set _not_implemented_set
2010-10-21 18:49:10 +04:00
GET_LV_STR_PROPERTY_FN ( lv_name , lv_name_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_name_set _not_implemented_set
2010-10-12 20:11:34 +04:00
GET_LV_STR_PROPERTY_FN ( lv_path , lv_path_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_path_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_STR_PROPERTY_FN ( lv_attr , lv_attr_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_attr_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_major , lv - > major )
2010-09-30 18:09:45 +04:00
# define _lv_major_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_minor , lv - > minor )
2010-09-30 18:09:45 +04:00
# define _lv_minor_set _not_implemented_set
2010-10-21 18:49:31 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_read_ahead , lv - > read_ahead * SECTOR_SIZE )
2010-09-30 18:09:45 +04:00
# define _lv_read_ahead_set _not_implemented_set
2010-10-12 20:12:33 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_kernel_major , lv_kernel_major ( lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_kernel_major_set _not_implemented_set
2010-10-12 20:12:33 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_kernel_minor , lv_kernel_minor ( lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_kernel_minor_set _not_implemented_set
2010-10-21 18:49:31 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_kernel_read_ahead , lv_kernel_read_ahead ( lv ) * SECTOR_SIZE )
2010-09-30 18:09:45 +04:00
# define _lv_kernel_read_ahead_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_NUM_PROPERTY_FN ( lv_size , lv - > size * SECTOR_SIZE )
2010-09-30 18:09:45 +04:00
# define _lv_size_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_NUM_PROPERTY_FN ( seg_count , dm_list_size ( & lv - > segments ) )
2010-09-30 18:09:45 +04:00
# define _seg_count_set _not_implemented_set
2010-10-21 18:49:20 +04:00
GET_LV_STR_PROPERTY_FN ( origin , lv_origin_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _origin_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LV_NUM_PROPERTY_FN ( origin_size , ( SECTOR_SIZE * lv_origin_size ( lv ) ) )
2010-09-30 18:09:45 +04:00
# define _origin_size_set _not_implemented_set
2010-12-15 02:20:58 +03:00
GET_LV_NUM_PROPERTY_FN ( snap_percent , _snap_percent ( lv ) )
2010-09-30 18:09:45 +04:00
# define _snap_percent_set _not_implemented_set
2010-12-15 02:20:58 +03:00
GET_LV_NUM_PROPERTY_FN ( copy_percent , _copy_percent ( lv ) )
2010-09-30 18:09:45 +04:00
# define _copy_percent_set _not_implemented_set
2012-10-24 06:19:27 +04:00
GET_LV_NUM_PROPERTY_FN ( sync_percent , _copy_percent ( lv ) )
# define _sync_percent_set _not_implemented_set
2013-04-12 00:33:59 +04:00
GET_LV_NUM_PROPERTY_FN ( mismatches , _mismatches ( lv ) )
# define _mismatches_set _not_implemented_set
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
GET_LV_NUM_PROPERTY_FN ( writebehind , _writebehind ( lv ) )
# define _writebehind_set _not_implemented_set
2013-05-31 20:25:52 +04:00
GET_LV_NUM_PROPERTY_FN ( minrecoveryrate , _minrecoveryrate ( lv ) )
# define _minrecoveryrate_set _not_implemented_set
GET_LV_NUM_PROPERTY_FN ( maxrecoveryrate , _maxrecoveryrate ( lv ) )
# define _maxrecoveryrate_set _not_implemented_set
2013-04-12 00:33:59 +04:00
GET_LV_STR_PROPERTY_FN ( syncaction , _sync_action ( lv ) )
# define _syncaction_set _not_implemented_set
2010-10-12 20:12:02 +04:00
GET_LV_STR_PROPERTY_FN ( move_pv , lv_move_pv_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _move_pv_set _not_implemented_set
2010-10-12 20:12:18 +04:00
GET_LV_STR_PROPERTY_FN ( convert_lv , lv_convert_lv_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _convert_lv_set _not_implemented_set
2010-10-12 20:11:20 +04:00
GET_LV_STR_PROPERTY_FN ( lv_tags , lv_tags_dup ( lv ) )
2010-09-30 18:09:45 +04:00
# define _lv_tags_set _not_implemented_set
2010-10-12 20:12:50 +04:00
GET_LV_STR_PROPERTY_FN ( mirror_log , lv_mirror_log_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _mirror_log_set _not_implemented_set
2010-10-12 20:13:06 +04:00
GET_LV_STR_PROPERTY_FN ( modules , lv_modules_dup ( lv - > vg - > vgmem , lv ) )
2010-09-30 18:09:45 +04:00
# define _modules_set _not_implemented_set
2012-01-19 19:34:32 +04:00
GET_LV_STR_PROPERTY_FN ( data_lv , lv_data_lv_dup ( lv - > vg - > vgmem , lv ) )
# define _data_lv_set _not_implemented_set
GET_LV_STR_PROPERTY_FN ( metadata_lv , lv_metadata_lv_dup ( lv - > vg - > vgmem , lv ) )
# define _metadata_lv_set _not_implemented_set
GET_LV_STR_PROPERTY_FN ( pool_lv , lv_pool_lv_dup ( lv - > vg - > vgmem , lv ) )
# define _pool_lv_set _not_implemented_set
GET_LV_NUM_PROPERTY_FN ( data_percent , _data_percent ( lv ) )
# define _data_percent_set _not_implemented_set
GET_LV_NUM_PROPERTY_FN ( metadata_percent , _metadata_percent ( lv ) )
# define _metadata_percent_set _not_implemented_set
GET_LV_NUM_PROPERTY_FN ( lv_metadata_size , lv_metadata_size ( lv ) * SECTOR_SIZE )
# define _lv_metadata_size_set _not_implemented_set
GET_LV_STR_PROPERTY_FN ( lv_time , lv_time_dup ( lv - > vg - > vgmem , lv ) )
# define _lv_time_set _not_implemented_set
GET_LV_STR_PROPERTY_FN ( lv_host , lv_host_dup ( lv - > vg - > vgmem , lv ) )
# define _lv_host_set _not_implemented_set
2013-04-25 14:12:05 +04:00
GET_LV_STR_PROPERTY_FN ( lv_active , lv_active_dup ( lv - > vg - > vgmem , lv ) )
# define _lv_active_set _not_implemented_set
2013-07-02 16:34:52 +04:00
GET_LV_STR_PROPERTY_FN ( lv_profile , lv_profile_dup ( lv - > vg - > vgmem , lv ) )
# define _lv_profile_set _not_implemented_set
2010-08-20 16:44:58 +04:00
/* VG */
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_fmt , vg_fmt_dup ( vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_fmt_set _not_implemented_set
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_uuid , vg_uuid_dup ( vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_uuid_set _not_implemented_set
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_name , vg_name_dup ( vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_name_set _not_implemented_set
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_attr , vg_attr_dup ( vg - > vgmem , vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_attr_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_size , ( SECTOR_SIZE * vg_size ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_size_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_free , ( SECTOR_SIZE * vg_free ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_free_set _not_implemented_set
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_sysid , vg_system_id_dup ( vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_sysid_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_extent_size , ( SECTOR_SIZE * vg - > extent_size ) )
2010-09-30 18:09:45 +04:00
# define _vg_extent_size_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_extent_count , vg - > extent_count )
2010-09-30 18:09:45 +04:00
# define _vg_extent_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_free_count , vg - > free_count )
2010-09-30 18:09:45 +04:00
# define _vg_free_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( max_lv , vg - > max_lv )
2010-09-30 18:09:45 +04:00
# define _max_lv_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( max_pv , vg - > max_pv )
2010-09-30 18:09:45 +04:00
# define _max_pv_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( pv_count , vg - > pv_count )
2010-09-30 18:09:45 +04:00
# define _pv_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( lv_count , ( vg_visible_lvs ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _lv_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( snap_count , ( snapshot_count ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _snap_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_seqno , vg - > seqno )
2010-09-30 18:09:45 +04:00
# define _vg_seqno_set _not_implemented_set
2010-09-30 18:08:58 +04:00
GET_VG_STR_PROPERTY_FN ( vg_tags , vg_tags_dup ( vg ) )
2010-09-30 18:09:45 +04:00
# define _vg_tags_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_mda_count , ( vg_mda_count ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_mda_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_mda_used_count , ( vg_mda_used_count ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_mda_used_count_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_mda_free , ( SECTOR_SIZE * vg_mda_free ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_mda_free_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_mda_size , ( SECTOR_SIZE * vg_mda_size ( vg ) ) )
2010-09-30 18:09:45 +04:00
# define _vg_mda_size_set _not_implemented_set
2010-09-30 18:08:46 +04:00
GET_VG_NUM_PROPERTY_FN ( vg_mda_copies , ( vg_mda_copies ( vg ) ) )
2010-11-17 22:15:10 +03:00
SET_VG_NUM_PROPERTY_FN ( vg_mda_copies , vg_set_mda_copies )
2013-07-02 16:34:52 +04:00
GET_VG_STR_PROPERTY_FN ( vg_profile , vg_profile_dup ( vg ) )
# define _vg_profile_set _not_implemented_set
2010-08-20 16:44:58 +04:00
/* LVSEG */
2011-03-05 15:14:00 +03:00
GET_LVSEG_STR_PROPERTY_FN ( segtype , lvseg_segtype_dup ( lvseg - > lv - > vg - > vgmem , lvseg ) )
2010-09-30 18:09:45 +04:00
# define _segtype_set _not_implemented_set
2010-11-17 23:08:14 +03:00
GET_LVSEG_NUM_PROPERTY_FN ( stripes , lvseg - > area_count )
2010-09-30 18:09:45 +04:00
# define _stripes_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( stripesize , ( SECTOR_SIZE * lvseg - > stripe_size ) )
2010-09-30 18:09:45 +04:00
# define _stripesize_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( stripe_size , ( SECTOR_SIZE * lvseg - > stripe_size ) )
2010-09-30 18:09:45 +04:00
# define _stripe_size_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( regionsize , ( SECTOR_SIZE * lvseg - > region_size ) )
2010-09-30 18:09:45 +04:00
# define _regionsize_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( region_size , ( SECTOR_SIZE * lvseg - > region_size ) )
2010-09-30 18:09:45 +04:00
# define _region_size_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( chunksize , ( SECTOR_SIZE * lvseg_chunksize ( lvseg ) ) )
2010-09-30 18:09:45 +04:00
# define _chunksize_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( chunk_size , ( SECTOR_SIZE * lvseg_chunksize ( lvseg ) ) )
2010-09-30 18:09:45 +04:00
# define _chunk_size_set _not_implemented_set
2012-01-19 19:34:32 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( thin_count , dm_list_size ( & lvseg - > lv - > segs_using_this_lv ) )
# define _thin_count_set _not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN ( zero , lvseg - > zero_new_blocks )
# define _zero_set _not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN ( transaction_id , lvseg - > transaction_id )
# define _transaction_id_set _not_implemented_set
2012-11-27 14:02:49 +04:00
GET_LVSEG_STR_PROPERTY_FN ( discards , lvseg_discards_dup ( lvseg - > lv - > vg - > vgmem , lvseg ) )
2012-08-08 00:24:41 +04:00
# define _discards_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_LVSEG_NUM_PROPERTY_FN ( seg_start , ( SECTOR_SIZE * lvseg_start ( lvseg ) ) )
2010-09-30 18:09:45 +04:00
# define _seg_start_set _not_implemented_set
2010-11-17 23:08:14 +03:00
GET_LVSEG_NUM_PROPERTY_FN ( seg_start_pe , lvseg - > le )
2010-09-30 18:09:45 +04:00
# define _seg_start_pe_set _not_implemented_set
2010-11-25 17:39:02 +03:00
GET_LVSEG_NUM_PROPERTY_FN ( seg_size , ( SECTOR_SIZE * lvseg_size ( lvseg ) ) )
2010-09-30 18:09:45 +04:00
# define _seg_size_set _not_implemented_set
2010-11-17 23:08:14 +03:00
GET_LVSEG_STR_PROPERTY_FN ( seg_tags , lvseg_tags_dup ( lvseg ) )
2010-09-30 18:09:45 +04:00
# define _seg_tags_set _not_implemented_set
2011-04-12 16:24:29 +04:00
GET_LVSEG_STR_PROPERTY_FN ( seg_pe_ranges ,
lvseg_seg_pe_ranges ( lvseg - > lv - > vg - > vgmem , lvseg ) )
2010-09-30 18:09:45 +04:00
# define _seg_pe_ranges_set _not_implemented_set
2011-04-12 16:24:29 +04:00
GET_LVSEG_STR_PROPERTY_FN ( devices , lvseg_devices ( lvseg - > lv - > vg - > vgmem , lvseg ) )
2010-09-30 18:09:45 +04:00
# define _devices_set _not_implemented_set
2013-04-25 14:07:57 +04:00
GET_LVSEG_STR_PROPERTY_FN ( monitor , lvseg_monitor_dup ( lvseg - > lv - > vg - > vgmem , lvseg ) )
# define _monitor_set _not_implemented_set
2010-08-20 16:44:58 +04:00
/* PVSEG */
2010-11-17 23:11:27 +03:00
GET_PVSEG_NUM_PROPERTY_FN ( pvseg_start , pvseg - > pe )
2010-09-30 18:09:45 +04:00
# define _pvseg_start_set _not_implemented_set
2012-11-29 13:29:03 +04:00
GET_PVSEG_NUM_PROPERTY_FN ( pvseg_size , ( SECTOR_SIZE * pvseg - > len ) )
2010-09-30 18:09:45 +04:00
# define _pvseg_size_set _not_implemented_set
2010-08-20 16:44:58 +04:00
# define STR DM_REPORT_FIELD_TYPE_STRING
# define NUM DM_REPORT_FIELD_TYPE_NUMBER
2010-10-21 18:49:43 +04:00
# define FIELD(type, strct, sorttype, head, field, width, fn, id, desc, settable) \
2010-10-25 18:08:32 +04:00
{ type , # id , settable , sorttype = = STR , sorttype = = NUM , { . integer = 0 } , _ # # id # # _get , _ # # id # # _set } ,
2010-08-20 16:44:58 +04:00
struct lvm_property_type _properties [ ] = {
# include "columns.h"
2010-10-25 18:08:32 +04:00
{ 0 , " " , 0 , 0 , 0 , { . integer = 0 } , _not_implemented_get , _not_implemented_set } ,
2010-08-20 16:44:58 +04:00
} ;
# undef STR
# undef NUM
# undef FIELD
2010-09-30 18:09:45 +04:00
static int _get_property ( const void * obj , struct lvm_property_type * prop ,
2012-02-27 15:45:05 +04:00
unsigned type )
2010-08-20 16:44:58 +04:00
{
struct lvm_property_type * p ;
p = _properties ;
while ( p - > id [ 0 ] ) {
if ( ! strcmp ( p - > id , prop - > id ) )
break ;
p + + ;
}
if ( ! p - > id [ 0 ] ) {
log_errno ( EINVAL , " Invalid property name %s " , prop - > id ) ;
return 0 ;
}
2010-09-30 18:09:45 +04:00
if ( ! ( p - > type & type ) ) {
log_errno ( EINVAL , " Property name %s does not match type %d " ,
prop - > id , p - > type ) ;
return 0 ;
}
2010-08-20 16:44:58 +04:00
* prop = * p ;
2010-09-30 18:09:45 +04:00
if ( ! p - > get ( obj , prop ) ) {
2010-08-20 16:44:58 +04:00
return 0 ;
}
2013-07-09 05:06:29 +04:00
2010-08-20 16:44:58 +04:00
return 1 ;
}
2010-09-30 18:09:45 +04:00
2010-11-17 22:15:10 +03:00
static int _set_property ( void * obj , struct lvm_property_type * prop ,
2012-02-27 15:45:05 +04:00
unsigned type )
2010-11-17 22:15:10 +03:00
{
struct lvm_property_type * p ;
p = _properties ;
while ( p - > id [ 0 ] ) {
if ( ! strcmp ( p - > id , prop - > id ) )
break ;
p + + ;
}
if ( ! p - > id [ 0 ] ) {
log_errno ( EINVAL , " Invalid property name %s " , prop - > id ) ;
return 0 ;
}
if ( ! p - > is_settable ) {
log_errno ( EINVAL , " Unable to set read-only property %s " ,
prop - > id ) ;
return 0 ;
}
if ( ! ( p - > type & type ) ) {
log_errno ( EINVAL , " Property name %s does not match type %d " ,
prop - > id , p - > type ) ;
return 0 ;
}
if ( p - > is_string )
p - > value . string = prop - > value . string ;
else
p - > value . integer = prop - > value . integer ;
if ( ! p - > set ( obj , p ) ) {
return 0 ;
}
2013-07-09 05:06:29 +04:00
2010-11-17 22:15:10 +03:00
return 1 ;
}
2010-11-17 23:08:14 +03:00
int lvseg_get_property ( const struct lv_segment * lvseg ,
struct lvm_property_type * prop )
{
return _get_property ( lvseg , prop , SEGS ) ;
}
2010-10-21 22:51:16 +04:00
int lv_get_property ( const struct logical_volume * lv ,
struct lvm_property_type * prop )
{
return _get_property ( lv , prop , LVS ) ;
}
2010-09-30 18:09:45 +04:00
int vg_get_property ( const struct volume_group * vg ,
struct lvm_property_type * prop )
{
return _get_property ( vg , prop , VGS ) ;
}
2010-11-17 23:11:27 +03:00
int pvseg_get_property ( const struct pv_segment * pvseg ,
struct lvm_property_type * prop )
{
return _get_property ( pvseg , prop , PVSEGS ) ;
}
2010-09-30 18:09:45 +04:00
int pv_get_property ( const struct physical_volume * pv ,
struct lvm_property_type * prop )
{
return _get_property ( pv , prop , PVS | LABEL ) ;
}
2010-11-17 22:15:10 +03:00
int lv_set_property ( struct logical_volume * lv ,
struct lvm_property_type * prop )
{
return _set_property ( lv , prop , LVS ) ;
}
int vg_set_property ( struct volume_group * vg ,
struct lvm_property_type * prop )
{
return _set_property ( vg , prop , VGS ) ;
}
int pv_set_property ( struct physical_volume * pv ,
struct lvm_property_type * prop )
{
return _set_property ( pv , prop , PVS | LABEL ) ;
}