2001-12-11 15:18:56 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2001-12-11 15:18:56 +03:00
*
2004-03-30 23:35:44 +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
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04: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
2001-12-11 15:18:56 +03:00
*/
2002-11-18 17:04:08 +03:00
# include "lib.h"
2001-12-11 15:18:56 +03:00
# include "metadata.h"
# include "import-export.h"
2001-12-20 14:52:54 +03:00
# include "lvm-string.h"
2001-12-11 15:18:56 +03:00
/*
* Bitsets held in the ' status ' flags get
* converted into arrays of strings .
*/
struct flag {
2009-11-25 01:55:55 +03:00
const uint64_t mask ;
2002-12-20 02:25:55 +03:00
const char * description ;
2008-07-10 15:30:57 +04:00
int kind ;
2001-12-11 15:18:56 +03:00
} ;
2010-01-07 17:47:57 +03:00
static const struct flag _vg_flags [ ] = {
2008-07-10 15:30:57 +04:00
{ EXPORTED_VG , " EXPORTED " , STATUS_FLAG } ,
{ RESIZEABLE_VG , " RESIZEABLE " , STATUS_FLAG } ,
{ PVMOVE , " PVMOVE " , STATUS_FLAG } ,
{ LVM_READ , " READ " , STATUS_FLAG } ,
{ LVM_WRITE , " WRITE " , STATUS_FLAG } ,
{ CLUSTERED , " CLUSTERED " , STATUS_FLAG } ,
{ SHARED , " SHARED " , STATUS_FLAG } ,
2008-09-19 10:42:00 +04:00
{ PARTIAL_VG , NULL , 0 } ,
2008-07-10 15:30:57 +04:00
{ PRECOMMITTED , NULL , 0 } ,
{ 0 , NULL , 0 }
2001-12-11 15:18:56 +03:00
} ;
2010-01-07 17:47:57 +03:00
static const struct flag _pv_flags [ ] = {
2008-07-10 15:30:57 +04:00
{ ALLOCATABLE_PV , " ALLOCATABLE " , STATUS_FLAG } ,
{ EXPORTED_VG , " EXPORTED " , STATUS_FLAG } ,
2008-09-19 10:42:00 +04:00
{ MISSING_PV , " MISSING " , COMPATIBLE_FLAG } ,
2008-07-10 15:30:57 +04:00
{ 0 , NULL , 0 }
2001-12-11 15:18:56 +03:00
} ;
2010-01-07 17:47:57 +03:00
static const struct flag _lv_flags [ ] = {
2008-07-10 15:30:57 +04:00
{ LVM_READ , " READ " , STATUS_FLAG } ,
{ LVM_WRITE , " WRITE " , STATUS_FLAG } ,
{ FIXED_MINOR , " FIXED_MINOR " , STATUS_FLAG } ,
{ VISIBLE_LV , " VISIBLE " , STATUS_FLAG } ,
{ PVMOVE , " PVMOVE " , STATUS_FLAG } ,
{ LOCKED , " LOCKED " , STATUS_FLAG } ,
{ MIRROR_NOTSYNCED , " NOTSYNCED " , STATUS_FLAG } ,
{ MIRROR_IMAGE , NULL , 0 } ,
{ MIRROR_LOG , NULL , 0 } ,
{ MIRRORED , NULL , 0 } ,
{ VIRTUAL , NULL , 0 } ,
{ SNAPSHOT , NULL , 0 } ,
2010-01-13 04:56:18 +03:00
{ MERGING , NULL , 0 } ,
2008-07-10 15:30:57 +04:00
{ ACTIVATE_EXCL , NULL , 0 } ,
{ CONVERTING , NULL , 0 } ,
2008-09-19 10:42:00 +04:00
{ PARTIAL_LV , NULL , 0 } ,
{ POSTORDER_FLAG , NULL , 0 } ,
2009-04-25 05:17:59 +04:00
{ VIRTUAL_ORIGIN , NULL , 0 } ,
2008-07-10 15:30:57 +04:00
{ 0 , NULL , 0 }
2001-12-11 15:18:56 +03:00
} ;
2010-01-07 17:47:57 +03:00
static const struct flag * _get_flags ( int type )
2001-12-11 15:18:56 +03:00
{
2008-07-10 15:30:57 +04:00
switch ( type & ~ STATUS_FLAG ) {
2001-12-11 15:18:56 +03:00
case VG_FLAGS :
return _vg_flags ;
case PV_FLAGS :
return _pv_flags ;
case LV_FLAGS :
return _lv_flags ;
}
2009-07-16 00:02:46 +04:00
log_error ( " Unknown flag set requested. " ) ;
2001-12-11 15:18:56 +03:00
return NULL ;
}
/*
* Converts a bitset to an array of string values ,
* using one of the tables defined at the top of
* the file .
*/
2009-11-25 01:55:55 +03:00
int print_flags ( uint64_t status , int type , char * buffer , size_t size )
2001-12-11 15:18:56 +03:00
{
2001-12-31 18:14:44 +03:00
int f , first = 1 ;
2010-01-07 17:47:57 +03:00
const struct flag * flags ;
2001-12-11 15:18:56 +03:00
2008-01-30 16:19:47 +03:00
if ( ! ( flags = _get_flags ( type ) ) )
return_0 ;
2001-12-11 15:18:56 +03:00
2003-09-18 00:35:57 +04:00
if ( ! emit_to_buffer ( & buffer , & size , " [ " ) )
2001-12-11 15:18:56 +03:00
return 0 ;
for ( f = 0 ; flags [ f ] . mask ; f + + ) {
if ( status & flags [ f ] . mask ) {
2004-05-05 22:15:47 +04:00
status & = ~ flags [ f ] . mask ;
2008-07-10 15:30:57 +04:00
if ( ( type & STATUS_FLAG ) ! = flags [ f ] . kind )
continue ;
2004-05-05 22:15:47 +04:00
/* Internal-only flag? */
if ( ! flags [ f ] . description )
continue ;
2001-12-20 14:52:54 +03:00
if ( ! first ) {
2003-09-18 00:35:57 +04:00
if ( ! emit_to_buffer ( & buffer , & size , " , " ) )
2001-12-20 14:52:54 +03:00
return 0 ;
} else
2001-12-11 15:18:56 +03:00
first = 0 ;
2004-05-05 22:15:47 +04:00
if ( ! emit_to_buffer ( & buffer , & size , " \" %s \" " ,
flags [ f ] . description ) )
2001-12-11 15:18:56 +03:00
return 0 ;
}
}
2003-09-18 00:35:57 +04:00
if ( ! emit_to_buffer ( & buffer , & size , " ] " ) )
2001-12-11 15:18:56 +03:00
return 0 ;
if ( status )
2002-01-29 20:23:33 +03:00
log_error ( " Metadata inconsistency: Not all flags successfully "
" exported. " ) ;
2001-12-11 15:18:56 +03:00
return 1 ;
}
2009-11-25 01:55:55 +03:00
int read_flags ( uint64_t * status , int type , struct config_value * cv )
2001-12-11 15:18:56 +03:00
{
int f ;
2009-11-25 01:55:55 +03:00
uint64_t s = UINT64_C ( 0 ) ;
2010-01-07 17:47:57 +03:00
const struct flag * flags ;
2001-12-11 15:18:56 +03:00
2008-01-30 16:19:47 +03:00
if ( ! ( flags = _get_flags ( type ) ) )
return_0 ;
2001-12-11 15:18:56 +03:00
2002-11-18 17:04:08 +03:00
if ( cv - > type = = CFG_EMPTY_ARRAY )
goto out ;
2001-12-11 15:18:56 +03:00
2002-11-18 17:04:08 +03:00
while ( cv ) {
if ( cv - > type ! = CFG_STRING ) {
2009-07-16 00:02:46 +04:00
log_error ( " Status value is not a string. " ) ;
2002-11-18 17:04:08 +03:00
return 0 ;
}
2002-08-01 16:51:48 +04:00
2002-11-18 17:04:08 +03:00
for ( f = 0 ; flags [ f ] . description ; f + + )
if ( ! strcmp ( flags [ f ] . description , cv - > v . str ) ) {
s | = flags [ f ] . mask ;
break ;
2001-12-11 15:18:56 +03:00
}
2008-09-19 10:42:00 +04:00
if ( type = = VG_FLAGS & & ! strcmp ( cv - > v . str , " PARTIAL " ) ) {
/*
* Exception : We no longer write this flag out , but it
* might be encountered in old backup files , so restore
* it in that case . It is never part of live metadata
* though , so only vgcfgrestore needs to be concerned
* by this case .
*/
s | = PARTIAL_VG ;
} else if ( ! flags [ f ] . description & & ( type & STATUS_FLAG ) ) {
2009-07-16 00:02:46 +04:00
log_error ( " Unknown status flag '%s'. " , cv - > v . str ) ;
2002-11-18 17:04:08 +03:00
return 0 ;
2001-12-11 15:18:56 +03:00
}
2002-11-18 17:04:08 +03:00
cv = cv - > next ;
2001-12-11 15:18:56 +03:00
}
2002-11-18 17:04:08 +03:00
out :
2008-07-10 15:30:57 +04:00
* status | = s ;
2001-12-11 15:18:56 +03:00
return 1 ;
}