2001-12-11 15:18:56 +03:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
* This file is released under the LGPL .
*/
2001-12-20 14:52:54 +03:00
# include "log.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 {
int mask ;
char * description ;
} ;
static struct flag _vg_flags [ ] = {
{ ACTIVE , " ACTIVE " } ,
{ EXPORTED_VG , " EXPORTED " } ,
{ EXTENDABLE_VG , " EXTENDABLE " } ,
{ CLUSTERED , " CLUSTERED " } ,
{ SHARED , " SHARED " } ,
{ 0 , NULL }
} ;
static struct flag _pv_flags [ ] = {
{ ACTIVE , " ACTIVE " } ,
{ ALLOCATED_PV , " ALLOCATED " } ,
{ 0 , NULL }
} ;
static struct flag _lv_flags [ ] = {
{ ACTIVE , " ACTIVE " } ,
2001-12-20 14:52:54 +03:00
{ LVM_READ , " READ " } ,
{ LVM_WRITE , " WRITE " } ,
2001-12-11 15:18:56 +03:00
{ ALLOC_SIMPLE , " ALLOC_SIMPLE " } ,
{ ALLOC_STRICT , " ALLOC_STRICT " } ,
{ ALLOC_CONTIGUOUS , " ALLOC_CONTIGUOUS " } ,
{ SNAPSHOT , " SNASHOT " } ,
{ SNAPSHOT_ORG , " SNAPSHOT_ORIGIN " } ,
{ 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 ;
}
2001-12-20 19:05:14 +03:00
static int _emit ( char * * buffer , size_t * size , const char * fmt , . . . )
{
size_t n ;
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 )
/* FIXME: agk is this the correct log level ? */
log_print ( " Not all flags were successfully exported, "
" possible bug. " ) ;
return 1 ;
}
int read_flags ( uint32_t * status , int type , struct config_value * cv )
{
int f ;
uint32_t s = 0 ;
struct flag * flags ;
if ( ! ( flags = _get_flags ( type ) ) ) {
stack ;
return 0 ;
}
while ( cv ) {
if ( cv ! = CFG_STRING ) {
log_err ( " Status value is not a string. " ) ;
return 0 ;
}
for ( f = 0 ; flags [ f ] . description ; f + + )
2001-12-20 14:52:54 +03:00
if ( ! strcmp ( flags [ f ] . description , cv - > v . str ) ) {
( * status ) & = flags [ f ] . mask ;
2001-12-11 15:18:56 +03:00
break ;
}
if ( ! flags [ f ] . description ) {
log_err ( " Unknown status flag. " ) ;
return 0 ;
}
cv = cv - > next ;
}
* status = s ;
return 1 ;
}