Skip to content

Commit

Permalink
Storable variables validator concept
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad1mir-D committed Jan 20, 2015
1 parent 2149d9f commit 9bf64ae
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 75 deletions.
4 changes: 2 additions & 2 deletions chunk_index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ ChunkIndex::ChunkIndex( EncryptionKey const & key, TmpMgr & tmpMgr,
{
if ( !prohibitChunkIndexLoading )
loadIndex( *this );
dPrintf( "Chunk index for %s is instantiated and initialized, hasKey: %s\n",
indexPath.c_str(), key.hasKey() ? "true" : "false" );
dPrintf( "%s for %s is instantiated and initialized, hasKey: %s\n",
__CLASS, indexPath.c_str(), key.hasKey() ? "true" : "false" );
}

Bundle::Id const * ChunkIndex::findChunk( ChunkId::RollingHashPart rollingHash,
Expand Down
111 changes: 79 additions & 32 deletions config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,32 +103,35 @@ static struct
Config::~Config()
{
// prevent memleak
if ( default_instance )
if ( want_cleanup )
delete storable;
}

Config::Config()
Config::Config():
want_cleanup( true )
{
ConfigInfo * configInfo = new ConfigInfo;
default_instance = true;
storable = configInfo;
dPrintf( "Config is instantiated and initialized with default values\n" );
dPrintf( "%s is instantiated and initialized with default values\n",
__CLASS );
}

Config::Config( ConfigInfo * configInfo )
Config::Config( ConfigInfo * configInfo ):
want_cleanup( false )
{
storable = configInfo;
default_instance = false;
dPrintf( "Config is instantiated and initialized with supplied ConfigInfo\n" );
dPrintf( "%s is instantiated and initialized with supplied ConfigInfo\n",
__CLASS );
}

Config::Config( const Config & configIn, ConfigInfo * configInfo )
Config::Config( const Config & configIn, ConfigInfo * configInfo ):
want_cleanup( false )
{
configInfo->MergeFrom( *configIn.storable );
*this = configIn;
storable = configInfo;
default_instance = false;
dPrintf( "Config is instantiated and initialized with supplied values\n" );
dPrintf( "%s is instantiated and initialized with supplied values\n",
__CLASS );
}

Config::OpCodes Config::parseToken( const char * option, const OptionType type )
Expand All @@ -150,28 +153,30 @@ Config::OpCodes Config::parseToken( const char * option, const OptionType type )
return Config::oBadOption;
}

bool Config::parseOption( const char * option, const OptionType type )
bool Config::parseOrValidate( const char * option, const OptionType type,
bool validate )
{
string prefix;
if ( type == Runtime )
prefix.assign( "runtime" );
else
if ( type == Storable )
prefix.assign( "storable" );
dPrintf( "Parsing %s option \"%s\"...\n", prefix.c_str(), option );

dPrintf( "%s %s option \"%s\"...\n", ( validate ? "Validating" : "Parsing" ),
prefix.c_str(), option );

bool hasValue = false;
size_t optionLength = strlen( option );
char optionName[ optionLength ], optionValue[ optionLength ];

if ( sscanf( option, "%[^=]=%s", optionName, optionValue ) == 2 )
{
dPrintf( "%s option name: %s, value: %s\n", prefix.c_str(),
optionName, optionValue );
dPrintf( "%s option %s: %s\n", prefix.c_str(), optionName, optionValue );
hasValue = true;
}
else
dPrintf( "%s option name: %s\n", prefix.c_str(), option );
dPrintf( "%s option %s\n", prefix.c_str(), option );

int opcode = parseToken( hasValue ? optionName : option, type );

Expand Down Expand Up @@ -391,17 +396,11 @@ bool Config::parseOption( const char * option, const OptionType type )

void Config::showHelp( const OptionType type )
{
string prefix;
if ( type == Runtime )
prefix.assign( "runtime" );
else
if ( type == Storable )
prefix.assign( "storable" );
fprintf( stderr,
"Available %s options overview:\n\n"
"== help ==\n"
"shows this message\n"
"", prefix.c_str() );
"show this message\n"
"", ( type == Runtime ? "runtime" : ( type == Storable ? "storable" : "" ) ) );

for ( u_int i = 0; ConfigHelper::keywords[ i ].name; i++ )
{
Expand All @@ -415,7 +414,7 @@ void Config::showHelp( const OptionType type )
}
}

bool Config::parse( const string & str, google::protobuf::Message * mutable_message )
bool Config::parseProto( const string & str, google::protobuf::Message * mutable_message )
{
return google::protobuf::TextFormat::ParseFromString( str, mutable_message );
}
Expand All @@ -428,10 +427,59 @@ string Config::toString( google::protobuf::Message const & message )
return str;
}

bool Config::validate( const string & configData, const string & newConfigData )
bool Config::validateProto( const string & configData, const string & newConfigData )
{
ConfigInfo newConfig;
return parse( newConfigData, &newConfig );
Config config;
dPrintf( "Validating proto...\n" );
if ( !parseProto( newConfigData, config.storable ) )
return false;

const ::google::protobuf::Descriptor * configDescriptor =
config.storable->descriptor();
for ( int i = 0; i < configDescriptor->field_count(); i++ )
{
const ::google::protobuf::FieldDescriptor * storage =
configDescriptor->field( i );
dPrintf( "Storage: %s - %d - %d\n", storage->name().c_str(),
storage->label(), storage->type());

// TODO: support for top-level fields
if ( storage->type() == ::google::protobuf::FieldDescriptor::TYPE_MESSAGE )
{
const ::google::protobuf::Descriptor * storageDescriptor =
storage->message_type();

for ( int j = 0; j < storageDescriptor->field_count(); j++ )
{
const ::google::protobuf::FieldDescriptor * field =
storageDescriptor->field( j );

dPrintf( "Field: %s - %d - %d\n", field->name().c_str(),
field->label(), field->type());

string option = storage->name() + "." + field->name();

if ( !config.parseOrValidate( option.c_str(), Storable, true ) )
{
fprintf( stderr, "Invalid option specified: %s\n",
option.c_str() );
return false;
}
}
}
}

return true;
}

void Config::reset_storable()
{
// TODO: Use protobuf introspection
// to fill messages in loop with default values
// without explicit declaration
SET_STORABLE( chunk, max_size, GET_STORABLE( chunk, max_size ) );
SET_STORABLE( bundle, max_payload_size, GET_STORABLE( bundle, max_payload_size ) );
SET_STORABLE( bundle, compression_method, GET_STORABLE( bundle, compression_method ) );
}

void Config::show()
Expand All @@ -449,20 +497,19 @@ bool Config::editInteractively( ZBackupBase * zbb )
string configData( toString( *zbb->config.storable ) );
string newConfigData( configData );

if ( !zbb->spawnEditor( newConfigData, &validate ) )
if ( !zbb->spawnEditor( newConfigData, &validateProto ) )
return false;

ConfigInfo newConfig;
if ( !parse( newConfigData, &newConfig ) )
return false;
parseProto( newConfigData, &newConfig );
if ( toString( *zbb->config.storable ) == toString( newConfig ) )
{
verbosePrintf( "No changes made to config\n" );
return false;
}

verbosePrintf( "Updating configuration...\n" );

zbb->config.storable->CopyFrom( newConfig );
zbb->config.storable->MergeFrom( newConfig );
verbosePrintf(
"Configuration successfully updated!\n"
"Updated configuration:\n%s", toString( *zbb->config.storable ).c_str() );
Expand Down
17 changes: 10 additions & 7 deletions config.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "mt.hh"
#include "backup_exchanger.hh"

// TODO: make *_storable to be variadic
#define SET_STORABLE( storage, property, value ) (\
{\
dPrintf( "storable->mutable_"#storage"()->set_"#property"( "#value" )\n" ); \
Expand Down Expand Up @@ -64,14 +65,14 @@ public:
oDeprecated, oUnsupported
} OpCodes;

// Validator for user-supplied configuration
static bool validate( const string &, const string & );
// Validator for user-supplied storable configuration
static bool validateProto( const string &, const string & );

static bool parse( const string & str, google::protobuf::Message * mutable_message );
static bool parseProto( const string &, google::protobuf::Message * );

static void showHelp( const OptionType );

static string toString( google::protobuf::Message const & message );
static string toString( google::protobuf::Message const & );

// Edit current configuration
// returns true if configuration is changed
Expand All @@ -81,18 +82,20 @@ public:
static void show( const ConfigInfo & );
void show();

OpCodes parseToken( const char * option, const OptionType );
bool parseOption( const char * option, const OptionType );
OpCodes parseToken( const char *, const OptionType );
bool parseOrValidate( const char *, const OptionType, bool validate = false );

Config( const Config &, ConfigInfo * );
Config( ConfigInfo * );
Config();
~Config();

void reset_storable();

RuntimeConfig runtime;
ConfigInfo * storable;
private:
bool default_instance;
bool want_cleanup;
};

#include "zbackup_base.hh"
Expand Down
4 changes: 4 additions & 0 deletions debug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
#define DEBUG_HH_INCLUDED__

#include <stdio.h>
#include <typeinfo>

// Macros we use to output debugging information

#define __CLASS typeid( *this ).name()

#ifndef NDEBUG

#define __FILE_BASE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
Expand All @@ -20,6 +23,7 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>

// TODO: pretty backtraces
#define dPrintBacktrace( ... ) ()
#else
#define dPrintBacktrace( ... ) ()
Expand Down
38 changes: 16 additions & 22 deletions zbackup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,23 +355,21 @@ int main( int argc, char *argv[] )
if ( strcmp( argv[ x ], "--exchange" ) == 0 && x + 1 < argc )
{
fprintf( stderr, "%s is deprecated, use -O exchange instead\n", argv[ x ] );
deprecated.assign( argv[ x ] + 2 );
deprecated.append( "=" );
deprecated.append( argv[ x + 1 ] );
deprecated = argv[ x ] + 2;//; + "=" + argv[ x + 1 ];
deprecated += "=";
deprecated += argv[ x + 1 ];
option = deprecated.c_str();
if ( option )
goto parse_option;
goto parse_option;
}
else
if ( strcmp( argv[ x ], "--threads" ) == 0 && x + 1 < argc )
{
fprintf( stderr, "%s is deprecated, use -O threads instead\n", argv[ x ] );
deprecated.assign( argv[ x ] + 2 );
deprecated.append( "=" );
deprecated.append( argv[ x + 1 ] );
deprecated = argv[ x ] + 2;
deprecated += "=";
deprecated += argv[ x + 1 ];
option = deprecated.c_str();
if ( option )
goto parse_option;
goto parse_option;
}
else
if ( strcmp( argv[ x ], "--cache-size" ) == 0 && x + 1 < argc )
Expand All @@ -383,25 +381,21 @@ int main( int argc, char *argv[] )
if ( sscanf( argv[ x + 1 ], "%zu %15s %n",
&cacheSizeMb, suffix, &n ) == 2 && !argv[ x + 1][ n ] )

deprecated.assign( argv[ x ] + 2 );
deprecated.append( "=" );
deprecated.append( Utils::numberToString( cacheSizeMb ) );
deprecated.append( "MiB" );
deprecated = argv[ x ] + 2;
deprecated += "=" + Utils::numberToString( cacheSizeMb ) + "MiB";
option = deprecated.c_str();
if ( option )
goto parse_option;
goto parse_option;
}
else
if ( strcmp( argv[ x ], "--compression" ) == 0 && x + 1 < argc )
{
fprintf( stderr, "%s is deprecated, use -o bundle.compression_method instead\n", argv[ x ] );
deprecated.assign( argv[ x ] + 2 );
deprecated.append( "=" );
deprecated.append( argv[ x + 1 ] );
deprecated = argv[ x ] + 2;
deprecated += "=";
deprecated += argv[ x + 1 ];
option = deprecated.c_str();
optionType = Config::Storable;
if ( option )
goto parse_option;
goto parse_option;
}
else
if ( strcmp( argv[ x ], "--help" ) == 0 || strcmp( argv[ x ], "-h" ) == 0 )
Expand Down Expand Up @@ -429,7 +423,7 @@ int main( int argc, char *argv[] )
else
{
parse_option:
if ( !config.parseOption( option, optionType ) )
if ( !config.parseOrValidate( option, optionType ) )
goto invalid_option;
}
}
Expand Down
Loading

0 comments on commit 9bf64ae

Please sign in to comment.