2001-12-11 12:18:56 +00:00
/*
2008-01-30 14:00:02 +00:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-20 20:55:30 +00:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2001-12-11 12:18:56 +00:00
*
2004-03-30 19:35:44 +00: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-20 20:55:30 +00:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 19:35:44 +00:00
*
2007-08-20 20:55:30 +00:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 19:35:44 +00: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 12:18:56 +00:00
*/
2002-11-18 14:04:08 +00:00
# include "lib.h"
2001-12-11 12:18:56 +00:00
# include "metadata.h"
# include "import-export.h"
2001-12-20 11:52:54 +00:00
# include "lvm-string.h"
2001-12-11 12:18:56 +00:00
/*
* Bitsets held in the ' status ' flags get
* converted into arrays of strings .
*/
struct flag {
2009-11-24 22:55:55 +00:00
const uint64_t mask ;
2002-12-19 23:25:55 +00:00
const char * description ;
2008-07-10 11:30:57 +00:00
int kind ;
2001-12-11 12:18:56 +00:00
} ;
2010-01-07 14:47:57 +00:00
static const struct flag _vg_flags [ ] = {
2008-07-10 11:30:57 +00: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 06:42:00 +00:00
{ PARTIAL_VG , NULL , 0 } ,
2008-07-10 11:30:57 +00:00
{ PRECOMMITTED , NULL , 0 } ,
{ 0 , NULL , 0 }
2001-12-11 12:18:56 +00:00
} ;
2010-01-07 14:47:57 +00:00
static const struct flag _pv_flags [ ] = {
2008-07-10 11:30:57 +00:00
{ ALLOCATABLE_PV , " ALLOCATABLE " , STATUS_FLAG } ,
{ EXPORTED_VG , " EXPORTED " , STATUS_FLAG } ,
2008-09-19 06:42:00 +00:00
{ MISSING_PV , " MISSING " , COMPATIBLE_FLAG } ,
2008-07-10 11:30:57 +00:00
{ 0 , NULL , 0 }
2001-12-11 12:18:56 +00:00
} ;
2010-01-07 14:47:57 +00:00
static const struct flag _lv_flags [ ] = {
2008-07-10 11:30:57 +00: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 01:56:18 +00:00
{ MERGING , NULL , 0 } ,
2008-07-10 11:30:57 +00:00
{ ACTIVATE_EXCL , NULL , 0 } ,
{ CONVERTING , NULL , 0 } ,
2008-09-19 06:42:00 +00:00
{ PARTIAL_LV , NULL , 0 } ,
{ POSTORDER_FLAG , NULL , 0 } ,
2009-04-25 01:17:59 +00:00
{ VIRTUAL_ORIGIN , NULL , 0 } ,
2010-05-21 12:36:30 +00:00
{ REPLICATOR , NULL , 0 } ,
{ REPLICATOR_LOG , NULL , 0 } ,
2008-07-10 11:30:57 +00:00
{ 0 , NULL , 0 }
2001-12-11 12:18:56 +00:00
} ;
2010-01-07 14:47:57 +00:00
static const struct flag * _get_flags ( int type )
2001-12-11 12:18:56 +00:00
{
2008-07-10 11:30:57 +00:00
switch ( type & ~ STATUS_FLAG ) {
2001-12-11 12:18:56 +00:00
case VG_FLAGS :
return _vg_flags ;
case PV_FLAGS :
return _pv_flags ;
case LV_FLAGS :
return _lv_flags ;
}
2009-07-15 20:02:46 +00:00
log_error ( " Unknown flag set requested. " ) ;
2001-12-11 12:18:56 +00: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-24 22:55:55 +00:00
int print_flags ( uint64_t status , int type , char * buffer , size_t size )
2001-12-11 12:18:56 +00:00
{
2001-12-31 15:14:44 +00:00
int f , first = 1 ;
2010-01-07 14:47:57 +00:00
const struct flag * flags ;
2001-12-11 12:18:56 +00:00
2008-01-30 13:19:47 +00:00
if ( ! ( flags = _get_flags ( type ) ) )
return_0 ;
2001-12-11 12:18:56 +00:00
2003-09-17 20:35:57 +00:00
if ( ! emit_to_buffer ( & buffer , & size , " [ " ) )
2001-12-11 12:18:56 +00:00
return 0 ;
for ( f = 0 ; flags [ f ] . mask ; f + + ) {
if ( status & flags [ f ] . mask ) {
2004-05-05 18:15:47 +00:00
status & = ~ flags [ f ] . mask ;
2008-07-10 11:30:57 +00:00
if ( ( type & STATUS_FLAG ) ! = flags [ f ] . kind )
continue ;
2004-05-05 18:15:47 +00:00
/* Internal-only flag? */
if ( ! flags [ f ] . description )
continue ;
2001-12-20 11:52:54 +00:00
if ( ! first ) {
2003-09-17 20:35:57 +00:00
if ( ! emit_to_buffer ( & buffer , & size , " , " ) )
2001-12-20 11:52:54 +00:00
return 0 ;
} else
2001-12-11 12:18:56 +00:00
first = 0 ;
2004-05-05 18:15:47 +00:00
if ( ! emit_to_buffer ( & buffer , & size , " \" %s \" " ,
flags [ f ] . description ) )
2001-12-11 12:18:56 +00:00
return 0 ;
}
}
2003-09-17 20:35:57 +00:00
if ( ! emit_to_buffer ( & buffer , & size , " ] " ) )
2001-12-11 12:18:56 +00:00
return 0 ;
if ( status )
2002-01-29 17:23:33 +00:00
log_error ( " Metadata inconsistency: Not all flags successfully "
" exported. " ) ;
2001-12-11 12:18:56 +00:00
return 1 ;
}
2009-11-24 22:55:55 +00:00
int read_flags ( uint64_t * status , int type , struct config_value * cv )
2001-12-11 12:18:56 +00:00
{
int f ;
2009-11-24 22:55:55 +00:00
uint64_t s = UINT64_C ( 0 ) ;
2010-01-07 14:47:57 +00:00
const struct flag * flags ;
2001-12-11 12:18:56 +00:00
2008-01-30 13:19:47 +00:00
if ( ! ( flags = _get_flags ( type ) ) )
return_0 ;
2001-12-11 12:18:56 +00:00
2002-11-18 14:04:08 +00:00
if ( cv - > type = = CFG_EMPTY_ARRAY )
goto out ;
2001-12-11 12:18:56 +00:00
2002-11-18 14:04:08 +00:00
while ( cv ) {
if ( cv - > type ! = CFG_STRING ) {
2009-07-15 20:02:46 +00:00
log_error ( " Status value is not a string. " ) ;
2002-11-18 14:04:08 +00:00
return 0 ;
}
2002-08-01 12:51:48 +00:00
2002-11-18 14:04:08 +00:00
for ( f = 0 ; flags [ f ] . description ; f + + )
if ( ! strcmp ( flags [ f ] . description , cv - > v . str ) ) {
s | = flags [ f ] . mask ;
break ;
2001-12-11 12:18:56 +00:00
}
2008-09-19 06:42:00 +00: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-15 20:02:46 +00:00
log_error ( " Unknown status flag '%s'. " , cv - > v . str ) ;
2002-11-18 14:04:08 +00:00
return 0 ;
2001-12-11 12:18:56 +00:00
}
2002-11-18 14:04:08 +00:00
cv = cv - > next ;
2001-12-11 12:18:56 +00:00
}
2002-11-18 14:04:08 +00:00
out :
2008-07-10 11:30:57 +00:00
* status | = s ;
2001-12-11 12:18:56 +00:00
return 1 ;
}