mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
310 lines
9.4 KiB
C++
310 lines
9.4 KiB
C++
#pragma once
|
|
#include "Backup.h"
|
|
#include "../Interface/Types.h"
|
|
#include "dao/ServerBackupDao.h"
|
|
#include <string>
|
|
#include "server_settings.h"
|
|
#include "../urbackupcommon/fileclient/FileClient.h"
|
|
#include "../urbackupcommon/fileclient/FileClientChunked.h"
|
|
#include <map>
|
|
#include "../urbackupcommon/file_metadata.h"
|
|
#include "server_log.h"
|
|
#include "FileMetadataDownloadThread.h"
|
|
#include <set>
|
|
|
|
class ClientMain;
|
|
class BackupServerHash;
|
|
class BackupServerPrepareHash;
|
|
class ServerPingThread;
|
|
class FileIndex;
|
|
class PhashLoad;
|
|
|
|
namespace
|
|
{
|
|
const unsigned int status_update_intervall=1000;
|
|
const unsigned int eta_update_intervall=60000;
|
|
const char* sync_fn = ".sync_f3a50226-f49a-4195-afef-c75b21781ae1";
|
|
}
|
|
|
|
struct SContinuousSequence
|
|
{
|
|
SContinuousSequence()
|
|
: id(-1), next(-1)
|
|
{
|
|
|
|
}
|
|
|
|
SContinuousSequence(int64 id, int64 next)
|
|
: id(id), next(next)
|
|
{
|
|
|
|
}
|
|
int64 id;
|
|
int64 next;
|
|
};
|
|
|
|
class FilePathCorrections
|
|
{
|
|
public:
|
|
FilePathCorrections()
|
|
: mutex(Server->createMutex()) {
|
|
|
|
}
|
|
void add(const std::string& path, const std::string& corr) {
|
|
IScopedLock lock(mutex.get());
|
|
filepath_corrections.insert(std::make_pair(path, corr));
|
|
}
|
|
bool get(const std::string& path, std::string& corr) {
|
|
IScopedLock lock(mutex.get());
|
|
std::map<std::string, std::string>::iterator it = filepath_corrections.find(path);
|
|
if (it != filepath_corrections.end())
|
|
{
|
|
corr = it->second;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
private:
|
|
std::unique_ptr<IMutex> mutex;
|
|
std::map<std::string, std::string> filepath_corrections;
|
|
};
|
|
|
|
class MaxFileId
|
|
{
|
|
public:
|
|
MaxFileId()
|
|
: mutex(Server->createMutex()),
|
|
max_downloaded(std::string::npos), max_preprocessed(0),
|
|
min_downloaded(0)
|
|
{}
|
|
|
|
void setMinDownloaded(size_t id)
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
if (max_downloaded>id)
|
|
{
|
|
max_downloaded = id;
|
|
}
|
|
min_downloaded = id+1;
|
|
}
|
|
|
|
void setMaxDownloaded(size_t id)
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
|
|
for (size_t i = 0; i < postponed.size();)
|
|
{
|
|
if (postponed[i] == id)
|
|
{
|
|
postponed.erase(postponed.begin() + i);
|
|
}
|
|
else if (id > postponed[i])
|
|
{
|
|
id = postponed[i] - 1;
|
|
++i;
|
|
}
|
|
else
|
|
{
|
|
++i;
|
|
}
|
|
}
|
|
|
|
max_downloaded = id + 1;
|
|
if (max_downloaded >= min_downloaded)
|
|
{
|
|
max_downloaded = std::string::npos;
|
|
}
|
|
}
|
|
|
|
void setMaxPreProcessed(size_t id)
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
max_preprocessed = id + 1;
|
|
}
|
|
|
|
bool isFinished(size_t id)
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
if (id + 1 <= max_downloaded
|
|
&& id + 1 <= max_preprocessed)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::string info()
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
std::string ret= "max_downloaded="+convert(max_downloaded)
|
|
+" max_preprocessed="+convert(max_preprocessed)
|
|
+" min_downloaded="+convert(min_downloaded)+" postponed.size="+convert(postponed.size());
|
|
|
|
if (!postponed.empty())
|
|
{
|
|
ret += " postponed:";
|
|
for (size_t i = 0; i < postponed.size(); ++i)
|
|
ret += " " + convert(postponed[i]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t get_max_preprocessed()
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
return max_preprocessed;
|
|
}
|
|
|
|
void postponeDownloaded(size_t id)
|
|
{
|
|
IScopedLock lock(mutex.get());
|
|
postponed.push_back(id);
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<IMutex> mutex;
|
|
size_t max_downloaded;
|
|
size_t max_preprocessed;
|
|
size_t min_downloaded;
|
|
std::vector<size_t> postponed;
|
|
};
|
|
|
|
class FileBackup : public Backup, public FileClient::ProgressLogCallback, public FileClient::NoFreeSpaceCallback,
|
|
public FileClientChunked::NoFreeSpaceCallback
|
|
{
|
|
public:
|
|
FileBackup(ClientMain* client_main, int clientid, std::string clientname, std::string subclientname, LogAction log_action,
|
|
bool is_incremental, int group, bool use_tmpfiles, std::string tmpfile_path, bool use_reflink, bool use_snapshots,
|
|
std::string server_token, std::string details, bool scheduled);
|
|
~FileBackup();
|
|
|
|
bool getResult();
|
|
bool hasEarlyError();
|
|
bool hasDiskError();
|
|
|
|
int getBackupid()
|
|
{
|
|
return backupid;
|
|
}
|
|
|
|
std::map<std::string, SContinuousSequence> getContinuousSequences()
|
|
{
|
|
return continuous_sequences;
|
|
}
|
|
|
|
static std::string convertToOSPathFromFileClient(std::string path);
|
|
|
|
static std::string fixFilenameForOS(std::string fn, std::set<std::string>& samedir_filenames, const std::string& curr_path, bool log_warnings, logid_t logid, FilePathCorrections& filepath_corrections);
|
|
|
|
virtual void log_progress(const std::string& fn, int64 total, int64 downloaded, int64 speed_bps);
|
|
|
|
virtual bool handle_not_enough_space(const std::string & path);
|
|
|
|
static bool create_hardlink(const std::string &linkname, const std::string &fname, bool use_ioref, bool* too_many_links, bool* copy);
|
|
|
|
protected:
|
|
virtual bool doBackup();
|
|
|
|
virtual bool doFileBackup() = 0;
|
|
|
|
ServerBackupDao::SDuration interpolateDurations(const std::vector<ServerBackupDao::SDuration>& durations);
|
|
bool request_filelist_construct(bool full, bool resume, int group,
|
|
bool with_token, bool& no_backup_dirs, bool& connect_fail, const std::string& clientsubname);
|
|
bool wait_for_async(const std::string& async_id, int64 timeout_time=10*60*1000);
|
|
bool request_client_write_tokens();
|
|
void logVssLogdata(int64 vss_duration_s);
|
|
bool getTokenFile(FileClient &fc, bool hashed_transfer, bool request);
|
|
std::string clientlistName(int ref_backupid);
|
|
void createHashThreads(bool use_reflink, bool ignore_hash_mismatches);
|
|
void destroyHashThreads();
|
|
_i64 getIncrementalSize(IFile *f, const std::vector<size_t> &diffs, bool& backup_with_components, bool all=false);
|
|
void calculateDownloadSpeed(int64 ctime, FileClient &fc, FileClientChunked* fc_chunked);
|
|
void calculateEtaFileBackup( int64 &last_eta_update, int64& eta_set_time, int64 ctime, FileClient &fc, FileClientChunked* fc_chunked,
|
|
int64 linked_bytes, int64 &last_eta_received_bytes, double &eta_estimated_speed, _i64 files_size );
|
|
bool hasChange(size_t line, const std::vector<size_t> &diffs);
|
|
bool link_file(const std::string &fn, const std::string &short_fn, const std::string &curr_path,
|
|
const std::string &os_path, const std::string& sha2, _i64 filesize, bool add_sql, FileMetadata& metadata);
|
|
void sendBackupOkay(bool b_okay);
|
|
void notifyClientBackupSuccessful(void);
|
|
void notifyClientBackupFailed();
|
|
void waitForFileThreads();
|
|
bool verify_file_backup(IFile *fileentries);
|
|
void save_debug_data(const std::string& rfn, const std::string& local_hash, const std::string& remote_hash);
|
|
std::string getSHA256(const std::string& fn);
|
|
std::string getSHA512(const std::string& fn);
|
|
std::string getSHADef(const std::string& fn);
|
|
bool constructBackupPath(bool on_snapshot, bool create_fs, std::string& errmsg);
|
|
bool constructBackupPathCdp();
|
|
std::string systemErrorInfo();
|
|
void saveUsersOnClient();
|
|
void createUserViews(IFile* file_list_f);
|
|
bool createUserView(IFile* file_list_f, const std::vector<int64>& ids, std::string accoutname, const std::vector<size_t>& identical_permission_roots);
|
|
std::vector<size_t> findIdenticalPermissionRoots(IFile* file_list_f, const std::vector<int64>& ids);
|
|
void deleteBackup();
|
|
bool createSymlink(const std::string& name, size_t depth, const std::string& symlink_target, const std::string& dir_sep, bool isdir);
|
|
bool startFileMetadataDownloadThread();
|
|
bool stopFileMetadataDownloadThread(bool stopped, size_t expected_embedded_metadata_files);
|
|
void parseSnapshotFailed(const std::string& logline);
|
|
std::string permissionsAllowAll();
|
|
bool loadWindowsBackupComponentConfigXml(FileClient &fc);
|
|
bool startPhashDownloadThread(const std::string& async_id);
|
|
bool stopPhashDownloadThread(const std::string& async_id);
|
|
bool checkRansomwareCanaries();
|
|
bool checkRansomwareCanariesInt(const std::string& last_backuppath, const std::string& ransomware_canary_paths);
|
|
bool checkRansomwareCanariesPath(const std::string& last_backuppath, const std::string& curr_path, const std::vector<std::string> path_components, size_t idx);
|
|
bool checkRansomwareCanaryFile(const std::string& last_backuppath, const std::string& curr_path, const std::string& fn_prefix);
|
|
|
|
int group;
|
|
bool use_tmpfiles;
|
|
std::string tmpfile_path;
|
|
bool use_reflink;
|
|
bool use_snapshots;
|
|
bool with_hashes;
|
|
bool cdp_path;
|
|
|
|
std::string backuppath;
|
|
std::string dir_pool_path;
|
|
std::string backuppath_hashes;
|
|
std::string backuppath_single;
|
|
|
|
IPipe *hashpipe;
|
|
IPipe *hashpipe_prepare;
|
|
std::vector<BackupServerHash*> bsh;
|
|
std::vector<THREADPOOL_TICKET> bsh_ticket;
|
|
std::vector<BackupServerPrepareHash*> bsh_prepare;
|
|
std::vector<THREADPOOL_TICKET> bsh_prepare_ticket;
|
|
std::unique_ptr<BackupServerHash> local_hash;
|
|
std::unique_ptr<BackupServerHash> local_hash2;
|
|
|
|
std::string filelist_async_id;
|
|
|
|
ServerPingThread* pingthread;
|
|
THREADPOOL_TICKET pingthread_ticket;
|
|
|
|
std::map<std::string, SContinuousSequence> continuous_sequences;
|
|
|
|
std::unique_ptr<FileIndex> fileindex;
|
|
|
|
bool disk_error;
|
|
|
|
int backupid;
|
|
|
|
std::unique_ptr<server::FileMetadataDownloadThread> metadata_download_thread;
|
|
THREADPOOL_TICKET metadata_download_thread_ticket;
|
|
std::unique_ptr<server::FileMetadataDownloadThread::FileMetadataApplyThread> metadata_apply_thread;
|
|
THREADPOOL_TICKET metadata_apply_thread_ticket;
|
|
|
|
FilePathCorrections filepath_corrections;
|
|
|
|
std::vector<std::string> shares_without_snapshot;
|
|
|
|
int64 last_speed_received_bytes;
|
|
int64 speed_set_time;
|
|
|
|
std::unique_ptr<PhashLoad> phash_load;
|
|
THREADPOOL_TICKET phash_load_ticket;
|
|
|
|
MaxFileId max_file_id;
|
|
};
|