2001-12-11 15:18:56 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*/
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 {
2002-12-20 02:25:55 +03:00
const int mask ;
const char * description ;
2001-12-11 15:18:56 +03:00
} ;
static struct flag _vg_flags [ ] = {
{ EXPORTED_VG , " EXPORTED " } ,
2002-01-10 18:09:51 +03:00
{ RESIZEABLE_VG , " RESIZEABLE " } ,
2002-01-29 20:23:33 +03:00
{ PARTIAL_VG , " PARTIAL " } ,
2003-05-06 16:02:36 +04:00
{ PVMOVE , " PVMOVE " } ,
2002-01-15 20:37:23 +03:00
{ LVM_READ , " READ " } ,
{ LVM_WRITE , " WRITE " } ,
2001-12-11 15:18:56 +03:00
{ CLUSTERED , " CLUSTERED " } ,
{ SHARED , " SHARED " } ,
{ 0 , NULL }
} ;
static struct flag _pv_flags [ ] = {
2002-01-10 18:09:51 +03:00
{ ALLOCATABLE_PV , " ALLOCATABLE " } ,
2002-01-29 20:23:33 +03:00
{ EXPORTED_VG , " EXPORTED " } ,
2001-12-11 15:18:56 +03:00
{ 0 , NULL }
} ;
static struct flag _lv_flags [ ] = {
2001-12-20 14:52:54 +03:00
{ LVM_READ , " READ " } ,
{ LVM_WRITE , " WRITE " } ,
2002-02-01 20:54:39 +03:00
{ FIXED_MINOR , " FIXED_MINOR " } ,
2002-07-11 19:28:49 +04:00
{ VISIBLE_LV , " VISIBLE " } ,
2003-05-06 16:02:36 +04:00
{ PVMOVE , " PVMOVE " } ,
{ LOCKED , " LOCKED " } ,
2001-12-11 15:18:56 +03:00
{ 0 , NULL }
} ;
2001-12-20 14:52:54 +03:00
static struct flag * _get_flags ( int type )
2001-12-11 15:18:56 +03:00
{
switch ( type ) {
case VG_FLAGS :
return _vg_flags ;
case PV_FLAGS :
return _pv_flags ;
case LV_FLAGS :
return _lv_flags ;
}
log_err ( " Unknown flag set requested. " ) ;
return NULL ;
}
2002-11-18 17:04:08 +03:00
static int _emit ( char * * buffer , size_t * size , const char * fmt , . . . )
2001-12-20 19:05:14 +03:00
{
2002-12-20 02:25:55 +03:00
int n ;
2001-12-20 19:05:14 +03:00
va_list ap ;
va_start ( ap , fmt ) ;
n = vsnprintf ( * buffer , * size , fmt , ap ) ;
va_end ( ap ) ;
2001-12-31 18:14:44 +03:00
if ( n < 0 | | ( n = = * size ) )
2001-12-20 19:05:14 +03:00
return 0 ;
* buffer + = n ;
* size - = n ;
return 1 ;
}
2001-12-11 15:18:56 +03:00
/*
* Converts a bitset to an array of string values ,
* using one of the tables defined at the top of
* the file .
*/
int print_flags ( uint32_t status , int type , char * buffer , size_t size )
{
2001-12-31 18:14:44 +03:00
int f , first = 1 ;
2001-12-11 15:18:56 +03:00
struct flag * flags ;
if ( ! ( flags = _get_flags ( type ) ) ) {
stack ;
return 0 ;
}
2001-12-20 19:05:14 +03:00
if ( ! _emit ( & buffer , & size , " [ " ) )
2001-12-11 15:18:56 +03:00
return 0 ;
for ( f = 0 ; flags [ f ] . mask ; f + + ) {
if ( status & flags [ f ] . mask ) {
2001-12-20 14:52:54 +03:00
if ( ! first ) {
2001-12-20 19:05:14 +03:00
if ( ! _emit ( & buffer , & size , " , " ) )
2001-12-20 14:52:54 +03:00
return 0 ;
} else
2001-12-11 15:18:56 +03:00
first = 0 ;
2001-12-20 19:05:14 +03:00
if ( ! _emit ( & buffer , & size , " \" %s \" " ,
flags [ f ] . description ) )
2001-12-11 15:18:56 +03:00
return 0 ;
status & = ~ flags [ f ] . mask ;
}
}
2001-12-20 19:05:14 +03:00
if ( ! _emit ( & 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 ;
}
2002-11-18 17:04:08 +03:00
int read_flags ( uint32_t * status , int type , struct config_value * cv )
2001-12-11 15:18:56 +03:00
{
int f ;
uint32_t s = 0 ;
struct flag * flags ;
if ( ! ( flags = _get_flags ( type ) ) ) {
stack ;
return 0 ;
}
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 ) {
log_err ( " Status value is not a string. " ) ;
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
}
2002-11-18 17:04:08 +03:00
if ( ! flags [ f ] . description ) {
log_err ( " Unknown status flag '%s'. " , cv - > v . str ) ;
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 :
2001-12-11 15:18:56 +03:00
* status = s ;
return 1 ;
}