mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
205 lines
5.4 KiB
C++
205 lines
5.4 KiB
C++
#include "PhashLoad.h"
|
|
#include "PhashLoad.h"
|
|
#include "PhashLoad.h"
|
|
#include "PhashLoad.h"
|
|
#include "PhashLoad.h"
|
|
#include "../urbackupcommon/fileclient/FileClient.h"
|
|
#include "../Interface/Server.h"
|
|
#include "../Interface/File.h"
|
|
#include "ClientMain.h"
|
|
#include "server_settings.h"
|
|
#include "database.h"
|
|
#include "../common/data.h"
|
|
|
|
extern std::string server_token;
|
|
|
|
PhashLoad::PhashLoad(FileClient* fc,
|
|
logid_t logid, std::string async_id)
|
|
: has_error(false), fc(fc),
|
|
logid(logid), async_id(async_id),
|
|
phash_file_pos(0), phash_file(NULL), eof(false),
|
|
has_timeout_error(false), orig_progress_log_callback(fc->getProgressLogCallback())
|
|
{
|
|
}
|
|
|
|
PhashLoad::~PhashLoad()
|
|
{
|
|
ScopedDeleteFile del_file(phash_file);
|
|
}
|
|
|
|
void PhashLoad::operator()()
|
|
{
|
|
fc->setProgressLogCallback(NULL);
|
|
fc->setNoFreeSpaceCallback(NULL);
|
|
|
|
std::string cfn = "SCRIPT|phash_{9c28ff72-5a74-487b-b5e1-8f1c96cd0cf4}/phash_" + async_id + "|0|0|" + server_token;
|
|
std::unique_ptr<IFsFile> phash_file_dl(Server->openTemporaryFile());
|
|
|
|
if (phash_file_dl.get() == NULL)
|
|
{
|
|
ServerLogger::Log(logid, "Error opening random file for parallel hash load. "+os_last_error_str(), LL_ERROR);
|
|
has_error = true;
|
|
return;
|
|
}
|
|
|
|
int mode = MODE_READ_SEQUENTIAL;
|
|
#ifdef _WIN32
|
|
mode = MODE_READ_DEVICE;
|
|
#endif
|
|
phash_file = Server->openFile(phash_file_dl->getFilename(), mode);
|
|
|
|
if(phash_file == NULL)
|
|
{
|
|
ScopedDeleteFn del_file(phash_file_dl->getFilename());
|
|
ServerLogger::Log(logid, "Error re-opening random file for parallel hash load. " + os_last_error_str(), LL_ERROR);
|
|
has_error = true;
|
|
return;
|
|
}
|
|
|
|
fc->setReconnectTries(5000);
|
|
_u32 rc = fc->GetFile(cfn, phash_file_dl.get(), true, false, 0, true, 0);
|
|
|
|
if (rc != ERR_SUCCESS)
|
|
{
|
|
ServerLogger::Log(logid, "Error during parallel hash load: "+fc->getErrorString(rc), LL_ERROR);
|
|
has_error = true;
|
|
|
|
if (rc == ERR_CONN_LOST || rc == ERR_TIMEOUT)
|
|
{
|
|
has_timeout_error = true;
|
|
}
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
ServerLogger::Log(logid, "Parallel hash loading finished successfully", LL_INFO);
|
|
fc->FinishScript(cfn);
|
|
}
|
|
|
|
eof = true;
|
|
}
|
|
|
|
bool PhashLoad::getHash(int64 file_id, std::string & hash)
|
|
{
|
|
while (true)
|
|
{
|
|
while (phash_file == NULL
|
|
|| phash_file_pos + static_cast<int64>(sizeof(_u16)) > phash_file->Size())
|
|
{
|
|
if ((has_error || eof)
|
|
&& phash_file_pos + static_cast<int64>(sizeof(_u16)) > phash_file->Size())
|
|
{
|
|
ServerLogger::Log(logid, "Getting parallel file hash record size of id " + convert(file_id) + " from " + phash_file->getFilename() + " failed. "
|
|
+ (eof ? "EOF." : "Had error."), LL_ERROR);
|
|
return false;
|
|
}
|
|
Server->wait(1000);
|
|
}
|
|
|
|
_u16 msgsize;
|
|
if (phash_file->Read(phash_file_pos, reinterpret_cast<char*>(&msgsize), sizeof(msgsize)) != sizeof(msgsize))
|
|
{
|
|
ServerLogger::Log(logid, "Error reading record size (" + convert(sizeof(msgsize)) +
|
|
" bytes) from parallel hash file " + phash_file->getFilename() + ". " + os_last_error_str(), LL_ERROR);
|
|
return false;
|
|
}
|
|
|
|
msgsize = little_endian(msgsize);
|
|
|
|
while (phash_file_pos + static_cast<int64>(sizeof(_u16)) + msgsize > phash_file->Size())
|
|
{
|
|
if ((has_error || eof)
|
|
&& phash_file_pos + static_cast<int64>(sizeof(_u16)) + msgsize > phash_file->Size())
|
|
{
|
|
ServerLogger::Log(logid, "Getting parallel file hash record data of id " + convert(file_id) + " from " + phash_file->getFilename() + " failed. "
|
|
+ (eof ? "EOF." : "Had error."), LL_ERROR);
|
|
return false;
|
|
}
|
|
Server->wait(1000);
|
|
}
|
|
|
|
std::string msgdata = phash_file->Read(phash_file_pos + sizeof(_u16), msgsize);
|
|
if (msgdata.size() != msgsize)
|
|
{
|
|
ServerLogger::Log(logid, "Error reading parallel hash file record (size "+convert(msgsize)+" read only "+convert(msgdata.size())+") "
|
|
"from parallel hash file " + phash_file->getFilename() + ". " + os_last_error_str(), LL_ERROR);
|
|
return false;
|
|
}
|
|
|
|
phash_file_pos += sizeof(_u16) + msgsize;
|
|
|
|
CRData data(msgdata.data(), msgdata.size());
|
|
char id;
|
|
if (!data.getChar(&id))
|
|
return false;
|
|
|
|
if (id == 0)
|
|
continue;
|
|
|
|
if (id != 1)
|
|
{
|
|
ServerLogger::Log(logid, "Unknown parallel hash file record id", LL_ERROR);
|
|
return false;
|
|
}
|
|
|
|
int64 curr_file_id;
|
|
if (!data.getVarInt(&curr_file_id))
|
|
{
|
|
ServerLogger::Log(logid, "Error reading parallel hash file id", LL_ERROR);
|
|
return false;
|
|
}
|
|
|
|
if (!data.getStr2(&hash))
|
|
{
|
|
ServerLogger::Log(logid, "Error reading parallel hash file hash", LL_ERROR);
|
|
return false;
|
|
}
|
|
|
|
if (curr_file_id > file_id)
|
|
{
|
|
phash_file_pos -= sizeof(_u16) + msgsize;
|
|
hash.clear();
|
|
ServerLogger::Log(logid, "Current parallel hash position greated than requested. "+convert(curr_file_id)+" > "+convert(file_id), LL_ERROR);
|
|
return false;
|
|
}
|
|
else if (curr_file_id < file_id)
|
|
{
|
|
ServerLogger::Log(logid, "Skip phash for id " + convert(curr_file_id) + " " + base64_encode_dash(hash), LL_DEBUG);
|
|
hash.clear();
|
|
continue;
|
|
}
|
|
|
|
ServerLogger::Log(logid, "Phash for id " + convert(file_id) + " is " + base64_encode_dash(hash), LL_DEBUG);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool PhashLoad::hasError()
|
|
{
|
|
return has_error;
|
|
}
|
|
|
|
void PhashLoad::shutdown()
|
|
{
|
|
fc->Shutdown();
|
|
}
|
|
|
|
bool PhashLoad::isDownloading()
|
|
{
|
|
return fc->isDownloading();
|
|
}
|
|
|
|
void PhashLoad::setProgressLogEnabled(bool b)
|
|
{
|
|
if (b)
|
|
{
|
|
fc->setProgressLogCallback(orig_progress_log_callback);
|
|
}
|
|
else
|
|
{
|
|
fc->setProgressLogCallback(NULL);
|
|
}
|
|
}
|