Initial support for backup exchange

Bundle and index exchange is under development yet
master
Am1GO 2014-09-30 14:36:28 +04:00
parent 55b9486473
commit 3cee914399
7 changed files with 143 additions and 30 deletions

View File

@ -1,12 +1,48 @@
// Part of ZBackup. Licensed under GNU GPLv2 or later
#include "storage_info_file.hh"
#include "backup_exchanger.hh"
#include "dir.hh"
#include "debug.hh"
namespace BackupExchanger {
BackupExchanger::BackupExchanger( )
vector< string > recreateDirectories( string const & src, string const & dst, string const & relaPath )
{
vector< string > files;
}
Dir::Listing lst ( Dir::addPath( src, relaPath ) );
Dir::Entry entry;
while ( lst.getNext( entry ) )
{
string curRelaPath ( relaPath );
if ( curRelaPath.empty() )
curRelaPath.assign( entry.getFileName() );
else
curRelaPath.assign( Dir::addPath( relaPath, entry.getFileName() ) );
if ( entry.isDir() )
{
verbosePrintf( "Found directory %s...\n", curRelaPath.c_str() );
string srcFullPath ( Dir::addPath( src, curRelaPath ) );
string dstFullPath ( Dir::addPath( dst, curRelaPath ) );
if ( !Dir::exists( dstFullPath.c_str() ) )
{
verbosePrintf( "Directory %s not found in destination, creating...\n",
curRelaPath.c_str() );
Dir::create( dstFullPath.c_str() );
}
vector< string > subFiles ( recreateDirectories( src, dst, curRelaPath ) );
files.insert( files.end(), subFiles.begin(), subFiles.end() );
}
else
{
verbosePrintf( "Found file %s...\n", curRelaPath.c_str() );
files.push_back( curRelaPath );
}
}
return files;
}
}

View File

@ -1,14 +1,15 @@
// Part of ZBackup. Licensed under GNU GPLv2 or later
#ifndef EXCHANGE_HH_INCLUDED__
#define EXCHANGE_HH_INCLUDED__
#ifndef BACKUP_EXCHANGER_HH_INCLUDED__
#define BACKUP_EXCHANGER_HH_INCLUDED__
#include <bitset>
#include <exception>
#include <string>
#include <vector>
using std::vector;
using std::string;
using std::vector;
namespace BackupExchanger {
@ -19,6 +20,8 @@ enum {
Flags
};
/// Recreate source directory structure in destination
vector< string > recreateDirectories( string const & src, string const & dst, string const & relaPath = std::string() );
}
#endif

View File

@ -66,11 +66,12 @@ void ChunkIndex::loadIndex()
}
ChunkIndex::ChunkIndex( EncryptionKey const & key, TmpMgr & tmpMgr,
string const & indexPath ):
string const & indexPath, bool prohibitChunkIndexLoading ):
key( key ), tmpMgr( tmpMgr ), indexPath( indexPath ), storage( 65536, 1 ),
lastBundleId( NULL )
{
loadIndex();
if ( !prohibitChunkIndexLoading )
loadIndex();
}
Bundle::Id const * ChunkIndex::findChunk( ChunkId::RollingHashPart rollingHash,

View File

@ -77,7 +77,7 @@ public:
DEF_EX( Ex, "Chunk index exception", std::exception )
DEF_EX( exIncorrectChunkIdSize, "Incorrect chunk id size encountered", Ex )
ChunkIndex( EncryptionKey const &, TmpMgr &, string const & indexPath );
ChunkIndex( EncryptionKey const &, TmpMgr &, string const & indexPath, bool prohibitChunkIndexLoading );
struct ChunkInfoInterface
{

View File

@ -9,6 +9,7 @@
#include "endian.hh"
#include "page_size.hh"
#include "random.hh"
#include "debug.hh"
namespace EncryptedFile {
@ -22,6 +23,7 @@ InputStream::InputStream( char const * fileName, EncryptionKey const & key,
buffer( std::max( getPageSize(), ( unsigned ) BlockSize * 2 ) ),
fill( 0 ), remainder( 0 ), backedUp( false )
{
dPrintf( "encrypted fileName: %s\n", fileName );
if ( key.hasKey() )
{
memcpy( iv, iv_, sizeof( iv ) );

View File

@ -24,10 +24,10 @@
#include "sptr.hh"
#include "storage_info_file.hh"
#include "zbackup.hh"
#include "backup_exchanger.hh"
using std::vector;
using std::bitset;
using std::iterator;
Paths::Paths( string const & storageDir ): storageDir( storageDir )
{
@ -63,7 +63,17 @@ ZBackupBase::ZBackupBase( string const & storageDir, string const & password ):
encryptionkey( password, storageInfo.has_encryption_key() ?
&storageInfo.encryption_key() : 0 ),
tmpMgr( getTmpPath() ),
chunkIndex( encryptionkey, tmpMgr, getIndexPath() )
chunkIndex( encryptionkey, tmpMgr, getIndexPath(), false )
{
}
ZBackupBase::ZBackupBase( string const & storageDir, string const & password,
bool prohibitChunkIndexLoading ):
Paths( storageDir ), storageInfo( loadStorageInfo() ),
encryptionkey( password, storageInfo.has_encryption_key() ?
&storageInfo.encryption_key() : 0 ),
tmpMgr( getTmpPath() ),
chunkIndex( encryptionkey, tmpMgr, getIndexPath(), prohibitChunkIndexLoading )
{
}
@ -112,10 +122,13 @@ void ZBackupBase::initStorage( string const & storageDir,
}
string ZBackupBase::deriveStorageDirFromBackupsFile( string const &
backupsFile )
backupsFile, bool allowOutside )
{
// TODO: handle cases when there's a backup/ folder within the backup/ folder
// correctly
if ( allowOutside )
return Dir::getRealPath( backupsFile );
string realPath = Dir::getRealPath( Dir::getDirName( backupsFile ) );
size_t pos;
if ( realPath.size() >= 8 && strcmp( realPath.c_str() + realPath.size() - 8,
@ -299,12 +312,59 @@ void ZRestore::restoreToStdin( string const & inputFileName )
ZExchange::ZExchange( string const & srcStorageDir, string const & srcPassword,
string const & dstStorageDir, string const & dstPassword,
bitset< BackupExchanger::Flags > const & exchange )
bool prohibitChunkIndexLoading ):
srcZBackupBase( srcStorageDir, srcPassword, prohibitChunkIndexLoading ),
dstZBackupBase( dstStorageDir, dstPassword, prohibitChunkIndexLoading )
{
}
void ZExchange::exchange()
void ZExchange::exchange( string const & srcPath, string const & dstPath,
bitset< BackupExchanger::Flags > const & exchange )
{
if ( exchange.test( BackupExchanger::backups ) )
{
BackupInfo backupInfo;
verbosePrintf( "Searching for backups...\n" );
vector< string > backups = BackupExchanger::recreateDirectories(
srcZBackupBase.getBackupsPath(), dstZBackupBase.getBackupsPath() );
for ( std::vector< string >::iterator it = backups.begin(); it != backups.end(); ++it )
{
verbosePrintf( "Processing backup file %s... ", it->c_str() );
string outputFileName ( Dir::addPath( dstZBackupBase.getBackupsPath(), *it ) );
if ( !File::exists( outputFileName ) )
{
BackupFile::load( Dir::addPath( srcZBackupBase.getBackupsPath(), *it ), srcZBackupBase.encryptionkey, backupInfo );
sptr< TemporaryFile > tmpFile = dstZBackupBase.tmpMgr.makeTemporaryFile();
BackupFile::save( tmpFile->getFileName(), dstZBackupBase.encryptionkey, backupInfo );
tmpFile->moveOverTo( outputFileName );
verbosePrintf( "done.\n" );
}
else
{
verbosePrintf( "file exists - skipped.\n" );
}
}
verbosePrintf( "Backup exchange completed.\n" );
}
if ( exchange.test( BackupExchanger::bundles ) )
{
verbosePrintf( "Searching for bundles...\n" );
verbosePrintf( "NOT IMPLEMENTED!\n" );
verbosePrintf( "Bundle exchange completed.\n" );
}
if ( exchange.test( BackupExchanger::index ) )
{
verbosePrintf( "Searching for indicies...\n" );
verbosePrintf( "NOT IMPLEMENTED!\n" );
verbosePrintf( "Index exchange completed.\n" );
}
}
DEF_EX( exExchangeWithLessThanTwoKeys, "Specify password flag (--non-encrypted or --password-file)"
@ -361,7 +421,7 @@ int main( int argc, char *argv[] )
exchange.set( BackupExchanger::index );
else
{
fprintf( stderr, "Invalid exchange value specified: %s. "
fprintf( stderr, "Invalid exchange value specified: %s\n"
"Must be one of the following: backups, bundles, index\n",
exchangeValue );
return EXIT_FAILURE;
@ -420,7 +480,11 @@ int main( int argc, char *argv[] )
args.push_back( argv[ x ] );
}
if ( args.size() < 1 )
if ( args.size() < 1 ||
( args.size() == 1 &&
( strcmp( args[ 0 ], "-h" ) == 0 || strcmp( args[ 0 ], "--help" ) == 0 )
)
)
{
fprintf( stderr,
"ZBackup, a versatile deduplicating backup tool, version 1.2\n"
@ -437,6 +501,7 @@ int main( int argc, char *argv[] )
" --cache-size <number> MB (default is %zu)\n"
" --exchange [backups|bundles|index] (can be\n"
" specified multiple times)\n"
" --help|-h show this message\n"
" Commands:\n"
" init <storage path> - initializes new storage;\n"
" backup <backup file name> - performs a backup from stdin;\n"
@ -518,23 +583,25 @@ int main( int argc, char *argv[] )
return EXIT_FAILURE;
}
string src, dst = 0;
int src, dst;
if ( strcmp( args[ 0 ], "export" ) == 0 )
{
src = args[ 1 ];
dst = args[ 2 ];
src = 1;
dst = 2;
}
else
if ( strcmp( args[ 0 ], "import" ) == 0 )
{
src = args[ 2 ];
dst = args[ 1 ];
src = 2;
dst = 1;
}
dPrintf( "%s src: %s\n", args[ 0 ], args[ src ] );
dPrintf( "%s dst: %s\n", args[ 0 ], args[ dst ] );
ZExchange ze( ZBackup::deriveStorageDirFromBackupsFile( src ), passwords[ 0 ],
ZBackup::deriveStorageDirFromBackupsFile( dst ), passwords[ 1 ],
exchange );
ze.exchange();
ZExchange ze( ZBackupBase::deriveStorageDirFromBackupsFile( args[ src ], true ), passwords[ src - 1 ],
ZBackupBase::deriveStorageDirFromBackupsFile( args[ dst ], true ), passwords[ dst - 1 ],
true );
ze.exchange( args[ src ], args[ dst ], exchange );
}
else
{

View File

@ -38,7 +38,7 @@ struct Paths
string getBackupsPath();
};
class ZBackupBase: protected Paths
class ZBackupBase: public Paths
{
public:
DEF_EX( Ex, "ZBackup exception", std::exception )
@ -54,6 +54,7 @@ public:
/// Opens the storage
ZBackupBase( string const & storageDir, string const & password );
ZBackupBase( string const & storageDir, string const & password, bool prohibitChunkIndexLoading );
/// Creates new storage
static void initStorage( string const & storageDir, string const & password,
@ -61,13 +62,13 @@ public:
/// For a given file within the backups/ dir in the storage, returns its
/// storage dir or throws an exception
static string deriveStorageDirFromBackupsFile( string const & backupsFile );
static string deriveStorageDirFromBackupsFile( string const & backupsFile, bool allowOutside = false );
protected:
StorageInfo storageInfo;
EncryptionKey encryptionkey;
TmpMgr tmpMgr;
ChunkIndex chunkIndex;
protected:
private:
StorageInfo loadStorageInfo();
@ -99,13 +100,16 @@ public:
class ZExchange
{
ZBackupBase srcZBackupBase;
ZBackupBase dstZBackupBase;
public:
ZExchange( string const & srcStorageDir, string const & srcPassword,
string const & dstStorageDir, string const & dstPassword,
bitset< BackupExchanger::Flags > const & exchange );
bool prohibitChunkIndexLoading );
/// Exchanges the data between storages
void exchange();
void exchange( string const & srcFileName, string const & dstFileName, bitset< BackupExchanger::Flags > const & exchange );
};
#endif