mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
Multiple virtual clients per real client
This commit is contained in:
parent
6447563c2e
commit
e90cb501ae
3
.gitignore
vendored
3
.gitignore
vendored
@ -231,3 +231,6 @@ urbackup/server_ident_ecdsa409k1.priv
|
||||
urbackup/server_ident_ecdsa409k1.pub
|
||||
clientctl/Debug/*
|
||||
urbackup/new_version_deb/*
|
||||
|
||||
urbackupserver/www/js/templates.js.new
|
||||
urbackupserver/www/templates.js.new
|
||||
|
||||
@ -48,6 +48,8 @@ AESGCMEncryption::AESGCMEncryption( const std::string& key, bool hash_password)
|
||||
encryption.SetKeyWithIV(m_sbbKey.BytePtr(), m_sbbKey.size(),
|
||||
m_IV.BytePtr(), m_IV.size());
|
||||
|
||||
m_orig_IV = m_IV;
|
||||
|
||||
iv_done=false;
|
||||
|
||||
assert(encryption.CanUseStructuredIVs());
|
||||
@ -64,9 +66,9 @@ void AESGCMEncryption::put( const char *data, size_t data_size )
|
||||
void AESGCMEncryption::flush()
|
||||
{
|
||||
encryption_filter.MessageEnd();
|
||||
end_markers.push_back(encryption_filter.MaxRetrievable());
|
||||
CryptoPP::IncrementCounterByOne(m_IV.BytePtr(), static_cast<unsigned int>(m_IV.size()));
|
||||
encryption.Resynchronize(m_IV.BytePtr(), static_cast<int>(m_IV.size()));
|
||||
end_markers.push_back(encryption_filter.MaxRetrievable());
|
||||
overhead_size+=16; //tag size
|
||||
}
|
||||
|
||||
@ -94,9 +96,9 @@ std::string AESGCMEncryption::get()
|
||||
|
||||
if(!iv_done)
|
||||
{
|
||||
memcpy(&ret[0], m_IV.BytePtr(), m_IV.size());
|
||||
memcpy(&ret[0], m_orig_IV.BytePtr(), m_orig_IV.size());
|
||||
iv_done=true;
|
||||
overhead_size+=m_IV.size();
|
||||
overhead_size+=m_orig_IV.size();
|
||||
}
|
||||
|
||||
if(max_retrievable>0)
|
||||
|
||||
@ -25,6 +25,7 @@ private:
|
||||
bool iv_done;
|
||||
CryptoPP::SecByteBlock m_sbbKey;
|
||||
CryptoPP::SecByteBlock m_IV;
|
||||
CryptoPP::SecByteBlock m_orig_IV;
|
||||
|
||||
CryptoPP::GCM<CryptoPP::AES >::Encryption encryption;
|
||||
CryptoPP::AuthenticatedEncryptionFilter encryption_filter;
|
||||
|
||||
@ -399,7 +399,7 @@ bool FileMetadataPipe::transmitCurrMetadata( char* buf, size_t buf_avail, size_t
|
||||
_u32 data_size = little_endian(static_cast<_u32>(data.getDataSize()));
|
||||
memcpy(metadata_buffer.data(), &data_size, sizeof(data_size));
|
||||
memcpy(metadata_buffer.data()+sizeof(data_size), data.getDataPtr(), data.getDataSize());
|
||||
metadata_buffer_size = data.getDataSize()+data_size;
|
||||
metadata_buffer_size = data.getDataSize()+sizeof(data_size);
|
||||
metadata_buffer_off=0;
|
||||
return transmitCurrMetadata(buf, buf_avail, read_bytes);
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "../Interface/Server.h"
|
||||
#include "../stringtools.h"
|
||||
#include "FileServ.h"
|
||||
#include "CUDPThread.h"
|
||||
|
||||
int start_server_int(unsigned short tcpport, unsigned short udpport, const std::string &pSname, const bool *pDostop, bool use_fqdn);
|
||||
|
||||
@ -97,3 +98,8 @@ IFileServ* FileServFactory::createFileServNoBind(const std::wstring &name, bool
|
||||
FileServ *fs=new FileServ(dostop, name, ILLEGAL_THREADPOOL_TICKET, use_fqdn_default);
|
||||
return fs;
|
||||
}
|
||||
|
||||
std::wstring FileServFactory::getDefaultServerName( bool use_fqdn )
|
||||
{
|
||||
return Server->ConvertToUnicode(getSystemServerName(use_fqdn));
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@ public:
|
||||
|
||||
static IPermissionCallback* getPermissionCallback();
|
||||
|
||||
std::wstring getDefaultServerName(bool use_fqdn);
|
||||
|
||||
private:
|
||||
static IPermissionCallback* permission_callback;
|
||||
static bool backupground_backups_enabled;
|
||||
|
||||
@ -16,6 +16,7 @@ public:
|
||||
virtual IFileServ * createFileServNoBind(const std::wstring &name=L"", bool use_fqdn_default=false)=0;
|
||||
virtual void destroyFileServ(IFileServ *filesrv)=0;
|
||||
virtual void setPermissionCallback(IPermissionCallback* new_permission_callback)=0;
|
||||
virtual std::wstring getDefaultServerName(bool use_fqdn)=0;
|
||||
};
|
||||
|
||||
#endif //IFILESERVFACTORY_H
|
||||
@ -365,7 +365,7 @@ string ExtractFileName(string fulln, string separators)
|
||||
bool separator = separators.find(fulln[i])!=string::npos;
|
||||
if(separator)
|
||||
{
|
||||
if(i<(s32)fulln.length()-2)
|
||||
if(i<(s32)fulln.length()-1)
|
||||
break;
|
||||
}
|
||||
if(fulln[i]!=0 && !separator)
|
||||
@ -386,7 +386,7 @@ wstring ExtractFileName(wstring fulln, wstring separators)
|
||||
|
||||
if( separator )
|
||||
{
|
||||
if(i<(s32)fulln.length()-2)
|
||||
if(i<(s32)fulln.length()-1)
|
||||
break;
|
||||
}
|
||||
if(fulln[i]!=0 && !separator)
|
||||
|
||||
@ -1055,12 +1055,12 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
bool ClientConnector::saveBackupDirs(str_map &args, bool server_default)
|
||||
bool ClientConnector::saveBackupDirs(str_map &args, bool server_default, int group_offset)
|
||||
{
|
||||
IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_CLIENT);
|
||||
db->BeginWriteTransaction();
|
||||
db_results backupdirs=db->Prepare("SELECT name, path FROM backupdirs")->Read();
|
||||
db->Prepare("DELETE FROM backupdirs WHERE symlinked=0")->Write();
|
||||
db->Prepare("DELETE FROM backupdirs WHERE symlinked=0 AND tgroup BETWEEN "+nconvert(group_offset)+" AND "+nconvert(group_offset+c_group_max))->Write();
|
||||
IQuery *q=db->Prepare("INSERT INTO backupdirs (name, path, server_default, optional, tgroup) VALUES (?, ? ,"+nconvert(server_default?1:0)+", ?, ?)");
|
||||
/**
|
||||
Use empty client settings
|
||||
@ -1090,11 +1090,11 @@ bool ClientConnector::saveBackupDirs(str_map &args, bool server_default)
|
||||
else
|
||||
name=ExtractFileName(dir);
|
||||
|
||||
int group = c_group_default;
|
||||
int group = group_offset + c_group_default;
|
||||
|
||||
str_map::iterator group_arg=args.find(L"dir_"+convert(i)+L"_group");
|
||||
if(group_arg!=args.end() && !group_arg->second.empty())
|
||||
group=watoi(group_arg->second);
|
||||
group=group_offset + watoi(group_arg->second);
|
||||
|
||||
int flags = EBackupDirFlag_FollowSymlinks | EBackupDirFlag_SymlinksOptional; //default flags
|
||||
size_t flags_off = name.find(L"/");
|
||||
@ -1220,7 +1220,7 @@ bool ClientConnector::saveBackupDirs(str_map &args, bool server_default)
|
||||
data.addChar(IndexThread::IndexThreadAction_RemoveWatchdir);
|
||||
data.addVoidPtr(contractor);
|
||||
data.addString(Server->ConvertToUTF8(backupdirs[i][L"path"]));
|
||||
if(watoi(backupdirs[i][L"group"])==c_group_continuous)
|
||||
if(watoi(backupdirs[i][L"group"])%c_group_size==c_group_continuous)
|
||||
{
|
||||
data.addString(Server->ConvertToUTF8(backupdirs[i][L"name"]));
|
||||
}
|
||||
@ -1348,9 +1348,23 @@ std::vector<std::wstring> getSettingsList(void);
|
||||
|
||||
void ClientConnector::updateSettings(const std::string &pData)
|
||||
{
|
||||
std::auto_ptr<ISettingsReader> curr_settings(Server->createFileSettingsReader("urbackup/data/settings.cfg"));
|
||||
std::auto_ptr<ISettingsReader> new_settings(Server->createMemorySettingsReader(pData));
|
||||
|
||||
std::string settings_fn="urbackup/data/settings.cfg";
|
||||
std::string settings_server_fn="urbackup/data/settings_"+server_token+".cfg";
|
||||
std::string clientsubname;
|
||||
std::string str_group_offset;
|
||||
int group_offset=0;
|
||||
if(new_settings->getValue("clientsubname", &clientsubname) && !clientsubname.empty()
|
||||
&& new_settings->getValue("filebackup_group_offset", &str_group_offset))
|
||||
{
|
||||
settings_fn = "urbackup/data/settings_"+conv_filename(clientsubname)+".cfg";
|
||||
settings_server_fn = "urbackup/data/settings_"+conv_filename(clientsubname) + "_"+server_token+".cfg";
|
||||
group_offset = atoi(str_group_offset.c_str());
|
||||
}
|
||||
|
||||
std::auto_ptr<ISettingsReader> curr_settings(Server->createFileSettingsReader(settings_fn));
|
||||
|
||||
std::vector<std::wstring> settings_names=getSettingsList();
|
||||
settings_names.push_back(L"client_set_settings");
|
||||
settings_names.push_back(L"client_set_settings_time");
|
||||
@ -1455,7 +1469,8 @@ void ClientConnector::updateSettings(const std::string &pData)
|
||||
}
|
||||
|
||||
IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_CLIENT);
|
||||
IQuery *q=db->Prepare("SELECT id FROM backupdirs WHERE server_default=0", false);
|
||||
IQuery *q=db->Prepare("SELECT id FROM backupdirs WHERE server_default=0 AND tgroup=?", false);
|
||||
q->Bind(group_offset);
|
||||
db_results res=q->Read();
|
||||
db->destroyQuery(q);
|
||||
if(res.empty())
|
||||
@ -1474,15 +1489,20 @@ void ClientConnector::updateSettings(const std::string &pData)
|
||||
std::wstring path=trim(def_dirs_toks[i]);
|
||||
std::wstring name;
|
||||
int group = c_group_default;
|
||||
if(path.find(L"|")!=std::string::npos)
|
||||
std::wstring first_path = path;
|
||||
if(path.find(L"/")!=std::string::npos)
|
||||
{
|
||||
first_path = getuntil(L"/", path);
|
||||
}
|
||||
if(first_path.find(L"|")!=std::string::npos)
|
||||
{
|
||||
std::vector<std::wstring> toks;
|
||||
Tokenize(default_dirs, toks, L"|");
|
||||
Tokenize(first_path, toks, L"|");
|
||||
name = toks[0];
|
||||
path = toks[1];
|
||||
if(toks.size()>2)
|
||||
{
|
||||
group = watoi(toks[2]);
|
||||
group = (std::min)(c_group_max, (std::max)(0, watoi(toks[2])));
|
||||
}
|
||||
}
|
||||
args[L"dir_"+convert(i)]=path;
|
||||
@ -1492,18 +1512,18 @@ void ClientConnector::updateSettings(const std::string &pData)
|
||||
args[L"dir_"+convert(i)+L"_group"]=convert(group);
|
||||
}
|
||||
|
||||
saveBackupDirs(args, true);
|
||||
saveBackupDirs(args, true, group_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if(mod)
|
||||
{
|
||||
writestring(Server->ConvertToUTF8(new_settings_str), "urbackup/data/settings.cfg");
|
||||
writestring(Server->ConvertToUTF8(new_settings_str), settings_fn);
|
||||
|
||||
InternetClient::updateSettings();
|
||||
}
|
||||
|
||||
std::auto_ptr<ISettingsReader> curr_server_settings(Server->createFileSettingsReader("urbackup/data/settings_"+server_token+".cfg"));
|
||||
std::auto_ptr<ISettingsReader> curr_server_settings(Server->createFileSettingsReader(settings_server_fn));
|
||||
std::vector<std::wstring> global_settings = getGlobalizedSettingsList();
|
||||
|
||||
std::wstring new_token_settings=L"";
|
||||
@ -1543,7 +1563,7 @@ void ClientConnector::updateSettings(const std::string &pData)
|
||||
|
||||
if(mod_server_settings)
|
||||
{
|
||||
writestring(Server->ConvertToUTF8(new_settings_str), "urbackup/data/settings_"+server_token+".cfg");
|
||||
writestring(Server->ConvertToUTF8(new_settings_str), settings_server_fn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1560,7 +1580,14 @@ void ClientConnector::replaceSettings(const std::string &pData)
|
||||
IndexThread::getMsgPipe()->Write(data.getDataPtr(), data.getDataSize());
|
||||
}
|
||||
|
||||
ISettingsReader* old_settings=Server->createFileSettingsReader("urbackup/data/settings.cfg");
|
||||
std::string settings_fn="urbackup/data/settings.cfg";
|
||||
std::string clientsubname;
|
||||
if(new_settings->getValue("clientsubname", &clientsubname) && !clientsubname.empty())
|
||||
{
|
||||
settings_fn = "urbackup/data/settings_"+conv_filename(clientsubname)+".cfg";
|
||||
}
|
||||
|
||||
ISettingsReader* old_settings=Server->createFileSettingsReader(settings_fn);
|
||||
|
||||
std::vector<std::wstring> new_keys = new_settings->getKeys();
|
||||
bool modified_settings=true;
|
||||
@ -1618,7 +1645,7 @@ void ClientConnector::replaceSettings(const std::string &pData)
|
||||
new_data+="client_set_settings=true\n";
|
||||
new_data+="client_set_settings_time="+nconvert(Server->getTimeSeconds())+"\n";
|
||||
|
||||
writestring(new_data, "urbackup/data/settings.cfg");
|
||||
writestring(new_data, settings_fn);
|
||||
}
|
||||
|
||||
Server->destroy(new_settings);
|
||||
@ -2442,11 +2469,16 @@ void ClientConnector::update_silent(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ClientConnector::calculateFilehashesOnClient(void)
|
||||
bool ClientConnector::calculateFilehashesOnClient(const std::string& clientsubname)
|
||||
{
|
||||
if(internet_conn)
|
||||
{
|
||||
ISettingsReader *curr_settings=Server->createFileSettingsReader("urbackup/data/settings.cfg");
|
||||
std::string settings_fn = "urbackup/data/settings.cfg";
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
settings_fn = "urbackup/data/settings_"+clientsubname+".cfg";
|
||||
}
|
||||
ISettingsReader *curr_settings=Server->createFileSettingsReader(settings_fn);
|
||||
|
||||
std::string val;
|
||||
if(curr_settings->getValue("internet_calculate_filehashes_on_client", &val)
|
||||
|
||||
@ -133,7 +133,7 @@ public:
|
||||
|
||||
private:
|
||||
bool checkPassword(const std::wstring &cmd, bool& change_pw);
|
||||
bool saveBackupDirs(str_map &args, bool server_default=false);
|
||||
bool saveBackupDirs(str_map &args, bool server_default=false, int group_offset=0);
|
||||
void updateLastBackup(void);
|
||||
std::string replaceChars(std::string in);
|
||||
void updateSettings(const std::string &pData);
|
||||
@ -155,7 +155,7 @@ private:
|
||||
void tochannelSendStartbackup(RunningAction backup_type);
|
||||
void ImageErr(const std::string &msg);
|
||||
void update_silent(void);
|
||||
bool calculateFilehashesOnClient(void);
|
||||
bool calculateFilehashesOnClient(const std::string& clientsubname);
|
||||
void sendStatus();
|
||||
bool sendChannelPacket(const SChannel& channel, const std::string& msg);
|
||||
|
||||
|
||||
@ -211,6 +211,14 @@ void ClientConnector::CMD_START_INCR_FILEBACKUP(const std::string &cmd)
|
||||
group = watoi(it_group->second);
|
||||
}
|
||||
|
||||
std::string clientsubname;
|
||||
|
||||
str_map::iterator it_clientsubname = params.find(L"clientsubname");
|
||||
if(it_clientsubname!=params.end())
|
||||
{
|
||||
clientsubname = conv_filename(Server->ConvertToUTF8(it_clientsubname->second));
|
||||
}
|
||||
|
||||
unsigned int flags = 0;
|
||||
|
||||
if(params.find(L"with_scripts")!=params.end())
|
||||
@ -238,7 +246,7 @@ void ClientConnector::CMD_START_INCR_FILEBACKUP(const std::string &cmd)
|
||||
flags |= flag_end_to_end_verification;
|
||||
}
|
||||
|
||||
if(calculateFilehashesOnClient())
|
||||
if(calculateFilehashesOnClient(clientsubname))
|
||||
{
|
||||
flags |= flag_calc_checksums;
|
||||
}
|
||||
@ -248,11 +256,12 @@ void ClientConnector::CMD_START_INCR_FILEBACKUP(const std::string &cmd)
|
||||
IScopedLock lock(backup_mutex);
|
||||
|
||||
CWData data;
|
||||
data.addChar(0);
|
||||
data.addChar(IndexThread::IndexThreadAction_StartIncrFileBackup);
|
||||
data.addVoidPtr(mempipe);
|
||||
data.addString(server_token);
|
||||
data.addInt(group);
|
||||
data.addInt(flags);
|
||||
data.addString(clientsubname);
|
||||
IndexThread::getMsgPipe()->Write(data.getDataPtr(), data.getDataSize());
|
||||
mempipe_owner=false;
|
||||
|
||||
@ -308,6 +317,13 @@ void ClientConnector::CMD_START_FULL_FILEBACKUP(const std::string &cmd)
|
||||
group = watoi(it_group->second);
|
||||
}
|
||||
|
||||
std::string clientsubname;
|
||||
str_map::iterator it_clientsubname = params.find(L"clientsubname");
|
||||
if(it_clientsubname!=params.end())
|
||||
{
|
||||
clientsubname = conv_filename(Server->ConvertToUTF8(it_clientsubname->second));
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
|
||||
if(params.find(L"with_scripts")!=params.end())
|
||||
@ -335,7 +351,7 @@ void ClientConnector::CMD_START_FULL_FILEBACKUP(const std::string &cmd)
|
||||
flags |= flag_end_to_end_verification;
|
||||
}
|
||||
|
||||
if(calculateFilehashesOnClient())
|
||||
if(calculateFilehashesOnClient(clientsubname))
|
||||
{
|
||||
flags |= flag_calc_checksums;
|
||||
}
|
||||
@ -345,11 +361,12 @@ void ClientConnector::CMD_START_FULL_FILEBACKUP(const std::string &cmd)
|
||||
IScopedLock lock(backup_mutex);
|
||||
|
||||
CWData data;
|
||||
data.addChar(1);
|
||||
data.addChar(IndexThread::IndexThreadAction_StartFullFileBackup);
|
||||
data.addVoidPtr(mempipe);
|
||||
data.addString(server_token);
|
||||
data.addInt(group);
|
||||
data.addInt(flags);
|
||||
data.addString(clientsubname);
|
||||
IndexThread::getMsgPipe()->Write(data.getDataPtr(), data.getDataSize());
|
||||
mempipe_owner=false;
|
||||
|
||||
|
||||
@ -119,7 +119,7 @@ void ImageThread::sendFullImageThread(void)
|
||||
if(!image_inf->shadowdrive.empty())
|
||||
{
|
||||
fs.reset(image_fak->createFilesystem(Server->ConvertToUnicode(image_inf->shadowdrive), true,
|
||||
IndexThread::backgroundBackupsEnabled(), true));
|
||||
IndexThread::backgroundBackupsEnabled(std::string()), true));
|
||||
shutdown_helper.reset(fs.get());
|
||||
}
|
||||
if(fs.get()==NULL)
|
||||
@ -435,7 +435,7 @@ void ImageThread::sendIncrImageThread(void)
|
||||
if(!image_inf->shadowdrive.empty())
|
||||
{
|
||||
fs.reset(image_fak->createFilesystem(Server->ConvertToUnicode(image_inf->shadowdrive), true,
|
||||
IndexThread::backgroundBackupsEnabled(), true));
|
||||
IndexThread::backgroundBackupsEnabled(std::string()), true));
|
||||
shutdown_helper.reset(fs.get());
|
||||
}
|
||||
if(fs.get()==NULL)
|
||||
|
||||
@ -254,7 +254,7 @@ void InternetClient::doUpdateSettings(void)
|
||||
&& !settings->getValue("computername_def", &computername) )
|
||||
|| computername.empty())
|
||||
{
|
||||
computername=Server->ConvertToUTF8(IndexThread::getFileSrv()->getServerName());
|
||||
computername=Server->ConvertToUTF8(IndexThread::getFileSrv()->getServerName());
|
||||
}
|
||||
if(settings->getValue("internet_server", &server_name) || settings->getValue("internet_server_def", &server_name) )
|
||||
{
|
||||
|
||||
@ -73,8 +73,12 @@ bool ServerIdentityMgr::checkServerSessionIdentity(const std::string &pIdentity,
|
||||
|
||||
for(size_t i=0;i<session_identities.size();++i)
|
||||
{
|
||||
int64 time = online_session_identities[i];
|
||||
if(time<0) time*=-1;
|
||||
|
||||
if(session_identities[i].ident==pIdentity
|
||||
&& session_identities[i].endpoint==endpoint)
|
||||
&& session_identities[i].endpoint==endpoint
|
||||
&& Server->getTimeMS()-time<ident_online_timeout)
|
||||
{
|
||||
online_session_identities[i]=Server->getTimeMS();
|
||||
return true;
|
||||
@ -187,7 +191,7 @@ void ServerIdentityMgr::loadServerIdentities(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
online_session_identities.push_back(0);
|
||||
online_session_identities.push_back(-1*Server->getTimeMS());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,7 +318,7 @@ void ServerIdentityMgr::addSessionIdentity( const std::string &pIdentity, const
|
||||
IScopedLock lock(mutex);
|
||||
SSessionIdentity session_ident = { pIdentity, endpoint};
|
||||
session_identities.push_back(session_ident);
|
||||
online_session_identities.push_back(0);
|
||||
online_session_identities.push_back(Server->getTimeMS());
|
||||
filesrv->addIdentity("#I"+pIdentity+"#");
|
||||
writeSessionIdentities();
|
||||
}
|
||||
@ -323,7 +327,7 @@ void ServerIdentityMgr::writeSessionIdentities()
|
||||
{
|
||||
IScopedLock lock(mutex);
|
||||
|
||||
const size_t max_session_identities=20;
|
||||
const size_t max_session_identities=1000;
|
||||
|
||||
size_t start=0;
|
||||
if(session_identities.size()>max_session_identities)
|
||||
@ -331,12 +335,26 @@ void ServerIdentityMgr::writeSessionIdentities()
|
||||
start=session_identities.size()-max_session_identities;
|
||||
}
|
||||
|
||||
size_t written = 0;
|
||||
std::string idents;
|
||||
for(size_t i=start;i<session_identities.size();++i)
|
||||
for(size_t i=session_identities.size(); i-- >0;)
|
||||
{
|
||||
if(!idents.empty()) idents+="\r\n";
|
||||
idents+=session_identities[i].ident;
|
||||
idents+="#endpoint="+session_identities[i].endpoint;
|
||||
int64 time = online_session_identities[i];
|
||||
if(time<0) time*=-1;
|
||||
|
||||
if(Server->getTimeMS()-time<ident_online_timeout)
|
||||
{
|
||||
if(!idents.empty()) idents+="\r\n";
|
||||
idents+=session_identities[i].ident;
|
||||
idents+="#endpoint="+session_identities[i].endpoint;
|
||||
|
||||
++written;
|
||||
if(written>=max_session_identities)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
write_file_only_admin(idents, server_session_ident_file);
|
||||
}
|
||||
|
||||
@ -57,6 +57,8 @@ volatile bool IdleCheckerThread::pause=false;
|
||||
volatile bool IndexThread::stop_index=false;
|
||||
std::map<std::wstring, std::wstring> IndexThread::filesrv_share_dirs;
|
||||
|
||||
const char IndexThread::IndexThreadAction_StartFullFileBackup=0;
|
||||
const char IndexThread::IndexThreadAction_StartIncrFileBackup=1;
|
||||
const char IndexThread::IndexThreadAction_GetLog=9;
|
||||
const char IndexThread::IndexThreadAction_PingShadowCopy=10;
|
||||
const char IndexThread::IndexThreadAction_AddWatchdir = 5;
|
||||
@ -361,7 +363,7 @@ void IndexThread::operator()(void)
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
|
||||
if(backgroundBackupsEnabled())
|
||||
if(backgroundBackupsEnabled(std::string()))
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
#ifdef THREAD_MODE_BACKGROUND_BEGIN
|
||||
@ -413,7 +415,7 @@ void IndexThread::operator()(void)
|
||||
char action;
|
||||
data.getChar(&action);
|
||||
data.getVoidPtr((void**)&contractor);
|
||||
if(action==0)
|
||||
if(action==IndexThreadAction_StartFullFileBackup)
|
||||
{
|
||||
Server->Log("Removing VSS log data...", LL_DEBUG);
|
||||
vsslog.clear();
|
||||
@ -422,6 +424,7 @@ void IndexThread::operator()(void)
|
||||
data.getInt(&index_group);
|
||||
unsigned int flags;
|
||||
data.getUInt(&flags);
|
||||
data.getStr(&index_clientsubname);
|
||||
|
||||
setFlags(flags);
|
||||
|
||||
@ -498,7 +501,7 @@ void IndexThread::operator()(void)
|
||||
contractor->Write("error - stop_index 1");
|
||||
}
|
||||
}
|
||||
else if(action==1)
|
||||
else if(action==IndexThreadAction_StartIncrFileBackup)
|
||||
{
|
||||
Server->Log("Removing VSS log data...", LL_DEBUG);
|
||||
vsslog.clear();
|
||||
@ -507,6 +510,7 @@ void IndexThread::operator()(void)
|
||||
data.getInt(&index_group);
|
||||
unsigned int flags;
|
||||
data.getUInt(&flags);
|
||||
data.getStr(&index_clientsubname);
|
||||
|
||||
setFlags(flags);
|
||||
|
||||
@ -1325,7 +1329,7 @@ bool IndexThread::readBackupScripts()
|
||||
{
|
||||
scripts.clear();
|
||||
|
||||
if(!with_scripts)
|
||||
if(!with_scripts || index_group!=c_group_default)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -2569,7 +2573,13 @@ void IndexThread::readPatterns(bool &pattern_changed, bool update_saved_patterns
|
||||
include_pattern_key=L"continuous_include_files";
|
||||
}
|
||||
|
||||
ISettingsReader *curr_settings=Server->createFileSettingsReader("urbackup/data/settings.cfg");
|
||||
std::string settings_fn = "urbackup/data/settings.cfg";
|
||||
if(!index_clientsubname.empty())
|
||||
{
|
||||
settings_fn = "urbackup/data/settings_"+index_clientsubname+".cfg";
|
||||
}
|
||||
|
||||
ISettingsReader *curr_settings=Server->createFileSettingsReader(settings_fn);
|
||||
exlude_dirs.clear();
|
||||
if(curr_settings!=NULL)
|
||||
{
|
||||
@ -2862,6 +2872,10 @@ void IndexThread::start_filesrv(void)
|
||||
curr_udpport=0;
|
||||
}
|
||||
|
||||
IFileServFactory* filesrv_fak = (IFileServFactory*)Server->getPlugin(Server->getThreadID(), filesrv_pluginid);
|
||||
|
||||
filesrv=filesrv_fak->createFileServ(curr_tcpport, curr_udpport, name, use_fqdn,
|
||||
backgroundBackupsEnabled(std::string()));
|
||||
filesrv->shareDir(L"urbackup", Server->getServerWorkingDir()+L"/urbackup/data", std::string());
|
||||
|
||||
ServerIdentityMgr::setFileServ(filesrv);
|
||||
@ -3415,9 +3429,16 @@ std::string IndexThread::escapeListName( const std::string& listname )
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IndexThread::backgroundBackupsEnabled()
|
||||
bool IndexThread::backgroundBackupsEnabled(const std::string& clientsubname)
|
||||
{
|
||||
std::auto_ptr<ISettingsReader> curr_settings(Server->createFileSettingsReader("urbackup/data/settings.cfg"));
|
||||
std::string settings_fn = "urbackup/data/settings.cfg";
|
||||
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
settings_fn = "urbackup/data/settings_"+conv_filename(clientsubname)+".cfg";
|
||||
}
|
||||
|
||||
std::auto_ptr<ISettingsReader> curr_settings(Server->createFileSettingsReader(settings_fn));
|
||||
if(curr_settings.get()!=NULL)
|
||||
{
|
||||
std::string background_backups;
|
||||
|
||||
@ -39,6 +39,8 @@
|
||||
|
||||
const int c_group_default = 0;
|
||||
const int c_group_continuous = 1;
|
||||
const int c_group_max = 99;
|
||||
const int c_group_size = 100;
|
||||
|
||||
const unsigned int flag_end_to_end_verification = 2;
|
||||
const unsigned int flag_with_scripts = 4;
|
||||
@ -142,6 +144,8 @@ class ClientDAO;
|
||||
class IndexThread : public IThread
|
||||
{
|
||||
public:
|
||||
static const char IndexThreadAction_StartFullFileBackup;
|
||||
static const char IndexThreadAction_StartIncrFileBackup;
|
||||
static const char IndexThreadAction_GetLog;
|
||||
static const char IndexThreadAction_PingShadowCopy;
|
||||
static const char IndexThreadAction_AddWatchdir;
|
||||
@ -168,7 +172,7 @@ public:
|
||||
|
||||
static void doStop(void);
|
||||
|
||||
static bool backgroundBackupsEnabled();
|
||||
static bool backgroundBackupsEnabled(const std::string& clientsubname);
|
||||
|
||||
static std::vector<std::wstring> parseExcludePatterns(const std::wstring& val);
|
||||
static std::vector<std::wstring> parseIncludePatterns(const std::wstring& val, std::vector<int>& include_depth,
|
||||
@ -322,6 +326,7 @@ private:
|
||||
|
||||
int index_group;
|
||||
int index_flags;
|
||||
std::string index_clientsubname;
|
||||
|
||||
SCDirs* index_scd;
|
||||
|
||||
|
||||
@ -477,10 +477,10 @@ std::string get_file_tokens( const std::wstring& fn, ClientDAO* dao, TokenCache&
|
||||
std::map<std::vector<char>, Token>::iterator token_it =
|
||||
token_cache.get()->tokens.find(sid);
|
||||
|
||||
assert(token_it->second.id!=0);
|
||||
|
||||
if(token_it!=token_cache.get()->tokens.end())
|
||||
{
|
||||
assert(token_it->second.id!=0);
|
||||
|
||||
if(allow)
|
||||
{
|
||||
token_info.addChar(ID_GRANT_ACCESS);
|
||||
|
||||
@ -102,7 +102,7 @@ size_t InternetServicePipe2::Read( char *buffer, size_t bsize, int timeoutms/*=-
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while(timeoutms>0 && Server->getTimeMS()-starttime<timeoutms);
|
||||
while(timeoutms==-1 || (timeoutms>0 && Server->getTimeMS()-starttime<timeoutms));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -607,27 +607,32 @@ bool FileClient::Reconnect(void)
|
||||
{
|
||||
transferred_bytes+=tcpsock->getTransferedBytes();
|
||||
real_transferred_bytes+=tcpsock->getRealTransferredBytes();
|
||||
IScopedLock lock(mutex);
|
||||
Server->destroy(tcpsock);
|
||||
tcpsock=NULL;
|
||||
}
|
||||
connect_starttime=Server->getTimeMS();
|
||||
|
||||
while(Server->getTimeMS()-connect_starttime<reconnection_timeout)
|
||||
{
|
||||
IPipe* new_tcpsock;
|
||||
if(reconnection_callback==NULL)
|
||||
{
|
||||
tcpsock=Server->ConnectStream(inet_ntoa(server_addr.sin_addr), TCP_PORT, 10000);
|
||||
new_tcpsock=Server->ConnectStream(inet_ntoa(server_addr.sin_addr), TCP_PORT, 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcpsock=reconnection_callback->new_fileclient_connection();
|
||||
new_tcpsock=reconnection_callback->new_fileclient_connection();
|
||||
}
|
||||
if(tcpsock!=NULL)
|
||||
if(new_tcpsock!=NULL)
|
||||
{
|
||||
for(size_t i=0;i<throttlers.size();++i)
|
||||
{
|
||||
tcpsock->addThrottler(throttlers[i]);
|
||||
new_tcpsock->addThrottler(throttlers[i]);
|
||||
}
|
||||
Server->Log("Reconnected successfully,", LL_DEBUG);
|
||||
IScopedLock lock(mutex);
|
||||
tcpsock = new_tcpsock;
|
||||
socket_open=true;
|
||||
return true;
|
||||
}
|
||||
@ -1491,6 +1496,10 @@ _i64 FileClient::getRealTransferredBytes()
|
||||
|
||||
void FileClient::Shutdown()
|
||||
{
|
||||
tcpsock->shutdown();
|
||||
IScopedLock lock(mutex);
|
||||
if(tcpsock!=NULL)
|
||||
{
|
||||
tcpsock->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ std::vector<SFile> getFiles(const std::wstring &path, bool *has_error)
|
||||
}
|
||||
std::wstring errmsg;
|
||||
int err = os_last_error(errmsg);
|
||||
Server->Log(L"Cannot open \""+path+L"\": "+errmsg+L" ("+convert(err)+L")", LL_ERROR);
|
||||
Log(L"Cannot open \""+path+L"\": "+errmsg+L" ("+convert(err)+L")", LL_ERROR);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -156,9 +156,9 @@ std::vector<SFile> getFiles(const std::wstring &path, bool *has_error)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring errmsg;
|
||||
std::wstring errmsg;
|
||||
int err = os_last_error(errmsg);
|
||||
Server->Log("Cannot stat \""+upath+dirp->d_name+"\": "+Server->ConvertToUTF8(errmsg)+" ("+nconvert(err)+")", LL_ERROR);
|
||||
Log("Cannot stat \""+upath+dirp->d_name+"\": "+ConvertToUTF8(errmsg)+" ("+nconvert(err)+")", LL_ERROR);
|
||||
if(has_error!=NULL)
|
||||
{
|
||||
*has_error=true;
|
||||
@ -181,7 +181,7 @@ std::vector<SFile> getFiles(const std::wstring &path, bool *has_error)
|
||||
{
|
||||
std::wstring errmsg;
|
||||
int err = os_last_error(errmsg);
|
||||
Server->Log(L"Error listing files in directory \""+path+L"\": "+errmsg+L" ("+convert(err)+L")", LL_ERROR);
|
||||
Log(L"Error listing files in directory \""+path+L"\": "+errmsg+L" ("+convert(err)+L")", LL_ERROR);
|
||||
if(has_error!=NULL)
|
||||
*has_error=true;
|
||||
}
|
||||
@ -696,7 +696,7 @@ int64 os_last_error(std::wstring& message)
|
||||
char* str = strerror(err);
|
||||
if(str!=NULL)
|
||||
{
|
||||
message = Server->ConvertToUnicode(str);
|
||||
message = ConvertToUnicode(str);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ std::vector<std::wstring> getSettingsList(void)
|
||||
ret.push_back(L"exclude_files");
|
||||
ret.push_back(L"include_files");
|
||||
ret.push_back(L"computername");
|
||||
ret.push_back(L"virtual_clients");
|
||||
ret.push_back(L"default_dirs");
|
||||
ret.push_back(L"allow_config_paths");
|
||||
ret.push_back(L"allow_starting_full_file_backups");
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
|
||||
extern IUrlFactory *url_fak;
|
||||
|
||||
Backup::Backup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool is_file_backup, bool is_incremental)
|
||||
: client_main(client_main), clientid(clientid), clientname(clientname), log_action(log_action),
|
||||
Backup::Backup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, bool is_file_backup, bool is_incremental)
|
||||
: client_main(client_main), clientid(clientid), clientname(clientname), clientsubname(clientsubname), log_action(log_action),
|
||||
is_file_backup(is_file_backup), r_incremental(is_incremental), r_resumed(false), backup_result(false),
|
||||
log_backup(true), has_early_error(false), should_backoff(true), db(NULL), status_id(0)
|
||||
{
|
||||
|
||||
@ -34,7 +34,7 @@ enum LogAction
|
||||
class Backup : public IThread
|
||||
{
|
||||
public:
|
||||
Backup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool is_file_backup, bool is_incremental);
|
||||
Backup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, bool is_file_backup, bool is_incremental);
|
||||
virtual ~Backup() {}
|
||||
|
||||
virtual void operator()();
|
||||
@ -70,6 +70,7 @@ protected:
|
||||
ClientMain* client_main;
|
||||
int clientid;
|
||||
std::wstring clientname;
|
||||
std::wstring clientsubname;
|
||||
LogAction log_action;
|
||||
|
||||
IDatabase* db;
|
||||
|
||||
@ -96,16 +96,18 @@ int ClientMain::restore_client_id = -1;
|
||||
|
||||
|
||||
ClientMain::ClientMain(IPipe *pPipe, sockaddr_in pAddr, const std::wstring &pName,
|
||||
bool internet_connection, bool use_snapshots, bool use_reflink)
|
||||
const std::wstring& pSubName, const std::wstring& pMainName, int filebackup_group_offset, bool internet_connection, bool use_snapshots, bool use_reflink)
|
||||
: internet_connection(internet_connection), server_settings(NULL), client_throttler(NULL),
|
||||
use_snapshots(use_snapshots), use_reflink(use_reflink),
|
||||
backup_dao(NULL), client_updated_time(0), continuous_backup(NULL)
|
||||
backup_dao(NULL), client_updated_time(0), continuous_backup(NULL),
|
||||
clientsubname(pSubName), filebackup_group_offset(filebackup_group_offset)
|
||||
{
|
||||
q_update_lastseen=NULL;
|
||||
pipe=pPipe;
|
||||
clientaddr=pAddr;
|
||||
clientaddr_mutex=Server->createMutex();
|
||||
clientname=pName;
|
||||
clientmainname=pMainName;
|
||||
clientid=0;
|
||||
|
||||
do_full_backup_now=false;
|
||||
@ -321,6 +323,10 @@ void ClientMain::operator ()(void)
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
else if(!clientsubname.empty())
|
||||
{
|
||||
backup_dao->setVirtualMainClient(clientmainname, clientid);
|
||||
}
|
||||
|
||||
logid = ServerLogger::getLogId(clientid);
|
||||
|
||||
@ -341,10 +347,11 @@ void ClientMain::operator ()(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if(server_settings->getSettings()->computername.empty())
|
||||
if(server_settings->getSettings()->computername.empty() || !clientsubname.empty())
|
||||
{
|
||||
server_settings->getSettings()->computername=clientname;
|
||||
}
|
||||
|
||||
if(server_settings->getImageFileFormat()==image_file_format_cowraw)
|
||||
{
|
||||
curr_image_version = curr_image_version & c_image_cowraw_bit;
|
||||
@ -420,6 +427,11 @@ void ClientMain::operator ()(void)
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
if(!server_settings->getSettings()->virtual_clients.empty())
|
||||
{
|
||||
BackupServer::setVirtualClients(clientname, server_settings->getSettings()->virtual_clients);
|
||||
}
|
||||
|
||||
ServerLogger::Log(logid, "Sending backup incr intervall...", LL_DEBUG);
|
||||
sendClientBackupIncrIntervall();
|
||||
|
||||
@ -464,6 +476,20 @@ void ClientMain::operator ()(void)
|
||||
ServerLogger::Log(logid, "Getting client settings failed -2", LL_ERROR);
|
||||
received_client_settings=false;
|
||||
}
|
||||
|
||||
if(server_settings->getImageFileFormat()==image_file_format_cowraw)
|
||||
{
|
||||
curr_image_version = curr_image_version & c_image_cowraw_bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_image_version = curr_image_version & ~c_image_cowraw_bit;
|
||||
}
|
||||
|
||||
if(!server_settings->getSettings()->virtual_clients.empty())
|
||||
{
|
||||
BackupServer::setVirtualClients(clientname, server_settings->getSettings()->virtual_clients);
|
||||
}
|
||||
}
|
||||
|
||||
if(settings_updated && (received_client_settings || settings_dont_exist) )
|
||||
@ -512,10 +538,10 @@ void ClientMain::operator ()(void)
|
||||
&& (!isRunningFileBackup(c_group_default) || do_full_backup_now) )
|
||||
{
|
||||
SRunningBackup backup;
|
||||
backup.backup = new FullFileBackup(this, clientid, clientname,
|
||||
do_full_backup_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled, c_group_default, use_tmpfiles,
|
||||
backup.backup = new FullFileBackup(this, clientid, clientname, clientsubname,
|
||||
do_full_backup_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled, filebackup_group_offset + c_group_default, use_tmpfiles,
|
||||
tmpfile_path, use_reflink, use_snapshots);
|
||||
backup.group=c_group_default;
|
||||
backup.group=filebackup_group_offset + c_group_default;
|
||||
|
||||
backup_queue.push_back(backup);
|
||||
|
||||
@ -528,10 +554,10 @@ void ClientMain::operator ()(void)
|
||||
&& (!isRunningFileBackup(c_group_default) || do_incr_backup_now) )
|
||||
{
|
||||
SRunningBackup backup;
|
||||
backup.backup = new IncrFileBackup(this, clientid, clientname,
|
||||
do_full_backup_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled, c_group_default, use_tmpfiles,
|
||||
backup.backup = new IncrFileBackup(this, clientid, clientname, clientsubname,
|
||||
do_full_backup_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled, filebackup_group_offset + c_group_default, use_tmpfiles,
|
||||
tmpfile_path, use_reflink, use_snapshots);
|
||||
backup.group=c_group_default;
|
||||
backup.group=filebackup_group_offset + c_group_default;
|
||||
|
||||
backup_queue.push_back(backup);
|
||||
|
||||
@ -550,7 +576,7 @@ void ClientMain::operator ()(void)
|
||||
if( (isUpdateFullImage(letter) && !isRunningImageBackup(letter)) || do_full_image_now )
|
||||
{
|
||||
SRunningBackup backup;
|
||||
backup.backup = new ImageBackup(this, clientid, clientname, do_full_image_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled,
|
||||
backup.backup = new ImageBackup(this, clientid, clientname, clientsubname, do_full_image_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled,
|
||||
false, letter);
|
||||
backup.letter=letter;
|
||||
|
||||
@ -572,7 +598,7 @@ void ClientMain::operator ()(void)
|
||||
if( (isUpdateIncrImage(letter) && !isRunningImageBackup(letter)) || do_incr_image_now )
|
||||
{
|
||||
SRunningBackup backup;
|
||||
backup.backup = new ImageBackup(this, clientid, clientname, do_full_image_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled,
|
||||
backup.backup = new ImageBackup(this, clientid, clientname, clientsubname, do_full_image_now?LogAction_AlwaysLog:LogAction_LogIfNotDisabled,
|
||||
true, letter);
|
||||
backup.letter=letter;
|
||||
|
||||
@ -587,7 +613,7 @@ void ClientMain::operator ()(void)
|
||||
cdp_needs_sync=false;
|
||||
|
||||
SRunningBackup backup;
|
||||
backup.backup = new ContinuousBackup(this, clientid, clientname,
|
||||
backup.backup = new ContinuousBackup(this, clientid, clientname, clientsubname,
|
||||
LogAction_LogIfNotDisabled, c_group_default, use_tmpfiles,
|
||||
tmpfile_path, use_reflink, use_snapshots);
|
||||
backup.group=c_group_continuous;
|
||||
@ -603,6 +629,8 @@ void ClientMain::operator ()(void)
|
||||
{
|
||||
if(Server->getThreadPool()->waitFor(backup_queue[i].ticket, 0))
|
||||
{
|
||||
ServerStatus::subRunningJob(clientmainname);
|
||||
|
||||
if(!backup_queue[i].backup->getResult() &&
|
||||
backup_queue[i].backup->shouldBackoff())
|
||||
{
|
||||
@ -650,11 +678,7 @@ void ClientMain::operator ()(void)
|
||||
size_t running_jobs=0;
|
||||
for(size_t i=0;i<backup_queue.size();++i)
|
||||
{
|
||||
if(backup_queue[i].ticket!=ILLEGAL_THREADPOOL_TICKET)
|
||||
{
|
||||
++running_jobs;
|
||||
}
|
||||
else
|
||||
if(backup_queue[i].ticket==ILLEGAL_THREADPOOL_TICKET)
|
||||
{
|
||||
can_start=true;
|
||||
}
|
||||
@ -662,16 +686,23 @@ void ClientMain::operator ()(void)
|
||||
|
||||
if(can_start)
|
||||
{
|
||||
while(running_jobs<server_settings->getSettings()->max_running_jobs_per_client)
|
||||
while(ServerStatus::numRunningJobs(clientmainname)<server_settings->getSettings()->max_running_jobs_per_client)
|
||||
{
|
||||
bool started_job=false;
|
||||
for(size_t i=0;i<backup_queue.size();++i)
|
||||
{
|
||||
if(backup_queue[i].ticket==ILLEGAL_THREADPOOL_TICKET)
|
||||
{
|
||||
backup_queue[i].ticket=Server->getThreadPool()->execute(backup_queue[i].backup);
|
||||
++running_jobs;
|
||||
started_job=true;
|
||||
ServerStatus::addRunningJob(clientmainname);
|
||||
if(ServerStatus::numRunningJobs(clientmainname)<=server_settings->getSettings()->max_running_jobs_per_client)
|
||||
{
|
||||
backup_queue[i].ticket=Server->getThreadPool()->execute(backup_queue[i].backup);
|
||||
started_job=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerStatus::subRunningJob(clientmainname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -756,6 +787,7 @@ void ClientMain::operator ()(void)
|
||||
if(backup_queue[i].ticket!=ILLEGAL_THREADPOOL_TICKET)
|
||||
{
|
||||
Server->getThreadPool()->waitFor(backup_queue[i].ticket);
|
||||
ServerStatus::subRunningJob(clientmainname);
|
||||
}
|
||||
|
||||
delete backup_queue[i].backup;
|
||||
@ -1239,6 +1271,12 @@ void ClientMain::sendSettings(void)
|
||||
{
|
||||
std::string s_settings;
|
||||
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
s_settings+="clientsubname="+Server->ConvertToUTF8(clientsubname)+"\n";
|
||||
s_settings+="filebackup_group_offset="+nconvert(filebackup_group_offset)+"\n";
|
||||
}
|
||||
|
||||
std::vector<std::wstring> settings_names=getSettingsList();
|
||||
std::vector<std::wstring> global_settings_names=getGlobalizedSettingsList();
|
||||
std::vector<std::wstring> local_settings_names=getLocalizedSettingsList();
|
||||
@ -1263,10 +1301,10 @@ void ClientMain::sendSettings(void)
|
||||
|
||||
ServerBackupDao::CondString origSettingsData = backup_dao->getOrigClientSettings(clientid);
|
||||
|
||||
ISettingsReader* origSettings = NULL;
|
||||
std::auto_ptr<ISettingsReader> origSettings;
|
||||
if(origSettingsData.exists)
|
||||
{
|
||||
origSettings = Server->createMemorySettingsReader(Server->ConvertToUTF8(origSettingsData.value));
|
||||
origSettings.reset(Server->createMemorySettingsReader(Server->ConvertToUTF8(origSettingsData.value)));
|
||||
}
|
||||
|
||||
for(size_t i=0;i<settings_names.size();++i)
|
||||
@ -1289,7 +1327,7 @@ void ClientMain::sendSettings(void)
|
||||
{
|
||||
s_settings+=Server->ConvertToUTF8(key)+"="+Server->ConvertToUTF8(value)+"\n";
|
||||
}
|
||||
else if(origSettings!=NULL)
|
||||
else if(origSettings.get()!=NULL)
|
||||
{
|
||||
std::wstring orig_v;
|
||||
if( (origSettings->getValue(key, &orig_v) ||
|
||||
@ -1313,7 +1351,6 @@ void ClientMain::sendSettings(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
delete origSettings;
|
||||
escapeClientMessage(s_settings);
|
||||
if(sendClientMessage("SETTINGS "+s_settings, "OK", L"Sending settings to client failed", 10000))
|
||||
{
|
||||
@ -1339,7 +1376,15 @@ bool ClientMain::getClientSettings(bool& doesnt_exist)
|
||||
ServerLogger::Log(logid, "Error creating temporary file in BackupServerGet::getClientSettings", LL_ERROR);
|
||||
return false;
|
||||
}
|
||||
rc=fc.GetFile("urbackup/settings.cfg", tmp, true, false);
|
||||
|
||||
std::string settings_fn = "urbackup/settings.cfg";
|
||||
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
settings_fn = "urbackup/settings_"+Server->ConvertToUTF8(clientsubname)+".cfg";
|
||||
}
|
||||
|
||||
rc=fc.GetFile(settings_fn, tmp, true, false);
|
||||
if(rc!=ERR_SUCCESS)
|
||||
{
|
||||
ServerLogger::Log(logid, L"Error getting Client settings of "+clientname+L". Errorcode: "+widen(fc.getErrorString(rc))+L" ("+convert(rc)+L")", LL_ERROR);
|
||||
@ -1437,15 +1482,6 @@ bool ClientMain::getClientSettings(bool& doesnt_exist)
|
||||
if(mod)
|
||||
{
|
||||
server_settings->update(true);
|
||||
|
||||
if(server_settings->getImageFileFormat()==image_file_format_cowraw)
|
||||
{
|
||||
curr_image_version = curr_image_version & c_image_cowraw_bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_image_version = curr_image_version & ~c_image_cowraw_bit;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1780,15 +1816,21 @@ IPipeThrottler *ClientMain::getThrottler(size_t speed_bps)
|
||||
|
||||
IPipe *ClientMain::getClientCommandConnection(int timeoutms, std::string* clientaddr)
|
||||
{
|
||||
std::string curr_clientname = Server->ConvertToUTF8(clientname);
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
curr_clientname = Server->ConvertToUTF8(clientmainname);
|
||||
}
|
||||
|
||||
if(clientaddr!=NULL)
|
||||
{
|
||||
unsigned int ip = ServerStatus::getStatus(clientname).ip_addr;
|
||||
unsigned int ip = ServerStatus::getStatus(Server->ConvertToUnicode(curr_clientname)).ip_addr;
|
||||
unsigned char *ips=reinterpret_cast<unsigned char*>(&ip);
|
||||
*clientaddr=nconvert(ips[0])+"."+nconvert(ips[1])+"."+nconvert(ips[2])+"."+nconvert(ips[3]);
|
||||
}
|
||||
if(internet_connection)
|
||||
{
|
||||
IPipe *ret=InternetServiceConnector::getConnection(Server->ConvertToUTF8(clientname), SERVICE_COMMANDS, timeoutms);
|
||||
IPipe *ret=InternetServiceConnector::getConnection(curr_clientname, SERVICE_COMMANDS, timeoutms);
|
||||
if(server_settings!=NULL && ret!=NULL)
|
||||
{
|
||||
int internet_speed=server_settings->getInternetSpeed();
|
||||
@ -1826,10 +1868,16 @@ IPipe *ClientMain::getClientCommandConnection(int timeoutms, std::string* client
|
||||
|
||||
_u32 ClientMain::getClientFilesrvConnection(FileClient *fc, ServerSettings* server_settings, int timeoutms)
|
||||
{
|
||||
std::string curr_clientname = Server->ConvertToUTF8(clientname);
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
curr_clientname = Server->ConvertToUTF8(clientmainname);
|
||||
}
|
||||
|
||||
fc->setProgressLogCallback(this);
|
||||
if(internet_connection)
|
||||
{
|
||||
IPipe *cp=InternetServiceConnector::getConnection(Server->ConvertToUTF8(clientname), SERVICE_FILESRV, timeoutms);
|
||||
IPipe *cp=InternetServiceConnector::getConnection(curr_clientname, SERVICE_FILESRV, timeoutms);
|
||||
|
||||
_u32 ret=fc->Connect(cp);
|
||||
|
||||
@ -1876,10 +1924,16 @@ _u32 ClientMain::getClientFilesrvConnection(FileClient *fc, ServerSettings* serv
|
||||
|
||||
bool ClientMain::getClientChunkedFilesrvConnection(std::auto_ptr<FileClientChunked>& fc_chunked, ServerSettings* server_settings, int timeoutms)
|
||||
{
|
||||
std::string curr_clientname = Server->ConvertToUTF8(clientname);
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
curr_clientname = Server->ConvertToUTF8(clientmainname);
|
||||
}
|
||||
|
||||
std::string identity = session_identity.empty()?server_identity:session_identity;
|
||||
if(internet_connection)
|
||||
{
|
||||
IPipe *cp=InternetServiceConnector::getConnection(Server->ConvertToUTF8(clientname), SERVICE_FILESRV, timeoutms);
|
||||
IPipe *cp=InternetServiceConnector::getConnection(curr_clientname, SERVICE_FILESRV, timeoutms);
|
||||
if(cp!=NULL)
|
||||
{
|
||||
fc_chunked.reset(new FileClientChunked(cp, false, &tcpstack, this, use_tmpfiles?NULL:this, identity, NULL));
|
||||
@ -1986,10 +2040,16 @@ void ClientMain::destroyTemporaryFile(IFile *tmp)
|
||||
|
||||
IPipe * ClientMain::new_fileclient_connection(void)
|
||||
{
|
||||
std::string curr_clientname = Server->ConvertToUTF8(clientname);
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
curr_clientname = Server->ConvertToUTF8(clientmainname);
|
||||
}
|
||||
|
||||
IPipe *rp=NULL;
|
||||
if(internet_connection)
|
||||
{
|
||||
rp=InternetServiceConnector::getConnection(Server->ConvertToUTF8(clientname), SERVICE_FILESRV, c_filesrv_connect_timeout);
|
||||
rp=InternetServiceConnector::getConnection(curr_clientname, SERVICE_FILESRV, c_filesrv_connect_timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -31,9 +31,10 @@ class BackupServerContinuous;
|
||||
class ContinuousBackup;
|
||||
class Backup;
|
||||
|
||||
const int c_group_all = -1;
|
||||
const int c_group_default = 0;
|
||||
const int c_group_continuous = 1;
|
||||
const int c_group_max = 99;
|
||||
const int c_group_size = 100;
|
||||
|
||||
struct SProtocolVersions
|
||||
{
|
||||
@ -94,7 +95,7 @@ class ClientMain : public IThread, public FileClientChunked::ReconnectionCallbac
|
||||
{
|
||||
friend class ServerHashExisting;
|
||||
public:
|
||||
ClientMain(IPipe *pPipe, sockaddr_in pAddr, const std::wstring &pName, bool internet_connection, bool use_snapshots, bool use_reflink);
|
||||
ClientMain(IPipe *pPipe, sockaddr_in pAddr, const std::wstring &pName, const std::wstring& pSubName, const std::wstring& pMainName, int filebackup_group_offset, bool internet_connection, bool use_snapshots, bool use_reflink);
|
||||
~ClientMain(void);
|
||||
|
||||
void operator()(void);
|
||||
@ -218,6 +219,9 @@ private:
|
||||
sockaddr_in clientaddr;
|
||||
IMutex *clientaddr_mutex;
|
||||
std::wstring clientname;
|
||||
std::wstring clientsubname;
|
||||
std::wstring clientmainname;
|
||||
int filebackup_group_offset;
|
||||
|
||||
std::wstring tmpfile_path;
|
||||
static size_t tmpfile_num;
|
||||
|
||||
@ -21,9 +21,9 @@
|
||||
#include "server_continuous.h"
|
||||
#include "IncrFileBackup.h"
|
||||
|
||||
ContinuousBackup::ContinuousBackup( ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action,
|
||||
ContinuousBackup::ContinuousBackup( ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action,
|
||||
int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots )
|
||||
: FileBackup(client_main, clientid, clientname, log_action, true, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots)
|
||||
: FileBackup(client_main, clientid, clientname, clientsubname, log_action, true, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots)
|
||||
{
|
||||
cdp_path=true;
|
||||
}
|
||||
@ -59,7 +59,7 @@ bool ContinuousBackup::doFileBackup()
|
||||
client_main->setContinuousBackup(continuous_update);
|
||||
}
|
||||
|
||||
IncrFileBackup incr_backup(client_main, clientid, clientname, LogAction_NoLogging, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots);
|
||||
IncrFileBackup incr_backup(client_main, clientid, clientname, clientsubname, LogAction_NoLogging, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots);
|
||||
incr_backup();
|
||||
|
||||
if(incr_backup.getResult())
|
||||
|
||||
@ -7,7 +7,7 @@ class BackupServerContinuous;
|
||||
class ContinuousBackup : public FileBackup
|
||||
{
|
||||
public:
|
||||
ContinuousBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action,
|
||||
ContinuousBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action,
|
||||
int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
|
||||
~ContinuousBackup();
|
||||
|
||||
@ -45,8 +45,8 @@ const unsigned int full_backup_construct_timeout=4*60*60*1000;
|
||||
extern std::string server_identity;
|
||||
extern std::string server_token;
|
||||
|
||||
FileBackup::FileBackup( ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool is_incremental, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots)
|
||||
: Backup(client_main, clientid, clientname, log_action, true, is_incremental), group(group), use_tmpfiles(use_tmpfiles), tmpfile_path(tmpfile_path), use_reflink(use_reflink), use_snapshots(use_snapshots),
|
||||
FileBackup::FileBackup( ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, bool is_incremental, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots)
|
||||
: Backup(client_main, clientid, clientname, clientsubname, log_action, true, is_incremental), group(group), use_tmpfiles(use_tmpfiles), tmpfile_path(tmpfile_path), use_reflink(use_reflink), use_snapshots(use_snapshots),
|
||||
disk_error(false), with_hashes(false),
|
||||
backupid(-1), hashpipe(NULL), hashpipe_prepare(NULL), bsh(NULL), bsh_prepare(NULL),
|
||||
bsh_ticket(ILLEGAL_THREADPOOL_TICKET), bsh_prepare_ticket(ILLEGAL_THREADPOOL_TICKET), pingthread(NULL),
|
||||
@ -92,7 +92,8 @@ bool FileBackup::getResult()
|
||||
return backup_result;
|
||||
}
|
||||
|
||||
bool FileBackup::request_filelist_construct(bool full, bool resume, int group, bool with_token, bool& no_backup_dirs, bool& connect_fail)
|
||||
bool FileBackup::request_filelist_construct(bool full, bool resume, int group,
|
||||
bool with_token, bool& no_backup_dirs, bool& connect_fail, const std::wstring& clientsubname)
|
||||
{
|
||||
if(server_settings->getSettings()->end_to_end_file_backup_verification)
|
||||
{
|
||||
@ -144,6 +145,10 @@ bool FileBackup::request_filelist_construct(bool full, bool resume, int group, b
|
||||
if(client_main->getProtocolVersions().file_protocol_version_v2>=1)
|
||||
{
|
||||
start_backup_cmd+=" group="+nconvert(group);
|
||||
if(!clientsubname.empty())
|
||||
{
|
||||
start_backup_cmd+="&clientsubname="+EscapeParamString(Server->ConvertToUTF8(clientsubname));
|
||||
}
|
||||
}
|
||||
|
||||
if(resume && client_main->getProtocolVersions().file_protocol_version_v2>=1)
|
||||
@ -177,7 +182,7 @@ bool FileBackup::request_filelist_construct(bool full, bool resume, int group, b
|
||||
{
|
||||
Server->destroy(cc);
|
||||
ServerLogger::Log(logid, clientname+L": Trying old filelist request", LL_WARNING);
|
||||
return request_filelist_construct(full, resume, group, false, no_backup_dirs, connect_fail);
|
||||
return request_filelist_construct(full, resume, group, false, no_backup_dirs, connect_fail, clientsubname);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -46,7 +46,7 @@ struct SContinuousSequence
|
||||
class FileBackup : public Backup
|
||||
{
|
||||
public:
|
||||
FileBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool is_incremental, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
FileBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring subclientname, LogAction log_action, bool is_incremental, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
~FileBackup();
|
||||
|
||||
bool getResult();
|
||||
@ -71,7 +71,8 @@ protected:
|
||||
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);
|
||||
bool request_filelist_construct(bool full, bool resume, int group,
|
||||
bool with_token, bool& no_backup_dirs, bool& connect_fail, const std::wstring& clientsubname);
|
||||
void logVssLogdata(int64 vss_duration_s);
|
||||
bool getTokenFile(FileClient &fc, bool hashed_transfer );
|
||||
std::string clientlistName( int group, bool new_list=false );
|
||||
|
||||
@ -396,7 +396,7 @@ bool FileMetadataDownloadThread::applyWindowsMetadata( IFile* metadata_f, IFile*
|
||||
|
||||
if(cont==0)
|
||||
{
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
WIN32_STREAM_ID_INT stream_id;
|
||||
|
||||
@ -34,8 +34,8 @@ extern std::string server_identity;
|
||||
extern std::string server_token;
|
||||
|
||||
|
||||
FullFileBackup::FullFileBackup( ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots )
|
||||
: FileBackup(client_main, clientid, clientname, log_action, false, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots)
|
||||
FullFileBackup::FullFileBackup( ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots )
|
||||
: FileBackup(client_main, clientid, clientname, clientsubname, log_action, false, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots)
|
||||
{
|
||||
|
||||
}
|
||||
@ -69,7 +69,7 @@ bool FullFileBackup::doFileBackup()
|
||||
|
||||
bool no_backup_dirs=false;
|
||||
bool connect_fail=false;
|
||||
bool b=request_filelist_construct(true, false, group, true, no_backup_dirs, connect_fail);
|
||||
bool b=request_filelist_construct(true, false, group, true, no_backup_dirs, connect_fail, clientsubname);
|
||||
if(!b)
|
||||
{
|
||||
has_early_error=true;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
class FullFileBackup : public FileBackup
|
||||
{
|
||||
public:
|
||||
FullFileBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
FullFileBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
|
||||
protected:
|
||||
virtual bool doFileBackup();
|
||||
|
||||
@ -99,8 +99,8 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
ImageBackup::ImageBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool incremental, std::string letter)
|
||||
: Backup(client_main, clientid, clientname, log_action, false, incremental), pingthread_ticket(ILLEGAL_THREADPOOL_TICKET), letter(letter), synthetic_full(false)
|
||||
ImageBackup::ImageBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, bool incremental, std::string letter)
|
||||
: Backup(client_main, clientid, clientname, clientsubname, log_action, false, incremental), pingthread_ticket(ILLEGAL_THREADPOOL_TICKET), letter(letter), synthetic_full(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ bool ImageBackup::doBackup()
|
||||
{
|
||||
ServerLogger::Log(logid, "Backing up SYSVOL...", LL_DEBUG);
|
||||
client_main->stopBackupRunning(false);
|
||||
ImageBackup sysvol_backup(client_main, clientid, clientname, LogAction_NoLogging, false, "SYSVOL");
|
||||
ImageBackup sysvol_backup(client_main, clientid, clientname, clientsubname, LogAction_NoLogging, false, "SYSVOL");
|
||||
sysvol_backup();
|
||||
|
||||
if(sysvol_backup.getResult())
|
||||
@ -173,7 +173,7 @@ bool ImageBackup::doBackup()
|
||||
{
|
||||
ServerLogger::Log(logid, "Backing up EFI System Partition...", LL_DEBUG);
|
||||
client_main->stopBackupRunning(false);
|
||||
ImageBackup esp_backup(client_main, clientid, clientname, LogAction_NoLogging, false, "ESP");
|
||||
ImageBackup esp_backup(client_main, clientid, clientname, clientsubname, LogAction_NoLogging, false, "ESP");
|
||||
esp_backup();
|
||||
|
||||
if(esp_backup.getResult())
|
||||
|
||||
@ -11,7 +11,7 @@ class ServerPingThread;
|
||||
class ImageBackup : public Backup
|
||||
{
|
||||
public:
|
||||
ImageBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action, bool incremental, std::string letter);
|
||||
ImageBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action, bool incremental, std::string letter);
|
||||
|
||||
int getBackupId()
|
||||
{
|
||||
|
||||
@ -40,9 +40,9 @@ extern std::string server_token;
|
||||
|
||||
const int64 c_readd_size_limit=100*1024;
|
||||
|
||||
IncrFileBackup::IncrFileBackup( ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action,
|
||||
IncrFileBackup::IncrFileBackup( ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action,
|
||||
int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots )
|
||||
: FileBackup(client_main, clientid, clientname, log_action, true, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots),
|
||||
: FileBackup(client_main, clientid, clientname, clientsubname, log_action, true, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots),
|
||||
intra_file_diffs(intra_file_diffs), hash_existing_mutex(NULL)
|
||||
{
|
||||
|
||||
@ -106,7 +106,7 @@ bool IncrFileBackup::doFileBackup()
|
||||
|
||||
bool no_backup_dirs=false;
|
||||
bool connect_fail = false;
|
||||
bool b=request_filelist_construct(resumed_full, resumed_backup, group, true, no_backup_dirs, connect_fail);
|
||||
bool b=request_filelist_construct(resumed_full, resumed_backup, group, true, no_backup_dirs, connect_fail, clientsubname);
|
||||
if(!b)
|
||||
{
|
||||
has_early_error=true;
|
||||
@ -1433,7 +1433,7 @@ bool IncrFileBackup::doFullBackup()
|
||||
|
||||
ServerStatus::stopProcess(clientname, status_id);
|
||||
|
||||
FullFileBackup full_backup(client_main, clientid, clientname, LogAction_NoLogging, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots);
|
||||
FullFileBackup full_backup(client_main, clientid, clientname, clientsubname, LogAction_NoLogging, group, use_tmpfiles, tmpfile_path, use_reflink, use_snapshots);
|
||||
full_backup();
|
||||
|
||||
disk_error = full_backup.hasDiskError();
|
||||
|
||||
@ -8,7 +8,7 @@ class FileMetadata;
|
||||
class IncrFileBackup : public FileBackup
|
||||
{
|
||||
public:
|
||||
IncrFileBackup(ClientMain* client_main, int clientid, std::wstring clientname, LogAction log_action,
|
||||
IncrFileBackup(ClientMain* client_main, int clientid, std::wstring clientname, std::wstring clientsubname, LogAction log_action,
|
||||
int group, bool use_tmpfiles, std::wstring tmpfile_path, bool use_reflink, bool use_snapshots);
|
||||
|
||||
void addExistingHash(const std::wstring& fullpath, const std::wstring& hashpath, const std::string& shahash, int64 filesize, int64 rsize);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -153,6 +153,7 @@ public:
|
||||
void addToOldBackupfolders(const std::wstring& backupfolder);
|
||||
std::vector<std::wstring> getOldBackupfolders(void);
|
||||
std::vector<std::wstring> getDeletePendingClientNames(void);
|
||||
CondString getVirtualMainClientname(int clientid);
|
||||
bool createTemporaryLastFilesTable(void);
|
||||
void dropTemporaryLastFilesTable(void);
|
||||
bool createTemporaryLastFilesTableIndex(void);
|
||||
@ -225,6 +226,7 @@ public:
|
||||
CondString getRestoreIdentity(int64 restore_id, int clientid);
|
||||
void setRestoreDone(int success, int64 restore_id);
|
||||
SFileBackupInfo getFileBackupInfo(int backupid);
|
||||
void setVirtualMainClient(const std::wstring& virtualmain, int64 clientid);
|
||||
//@-SQLGenFunctionsEnd
|
||||
|
||||
int64 addFileEntryExternal(int backupid, const std::wstring& fullpath, const std::wstring& hashpath, const std::string& shahash, int64 filesize, int64 rsize, int clientid, int incremental, int64 next_entry, int64 prev_entry, int pointed_to);
|
||||
@ -252,6 +254,7 @@ private:
|
||||
IQuery* q_addToOldBackupfolders;
|
||||
IQuery* q_getOldBackupfolders;
|
||||
IQuery* q_getDeletePendingClientNames;
|
||||
IQuery* q_getVirtualMainClientname;
|
||||
IQuery* q_createTemporaryLastFilesTable;
|
||||
IQuery* q_dropTemporaryLastFilesTable;
|
||||
IQuery* q_createTemporaryLastFilesTableIndex;
|
||||
@ -324,6 +327,7 @@ private:
|
||||
IQuery* q_getRestoreIdentity;
|
||||
IQuery* q_setRestoreDone;
|
||||
IQuery* q_getFileBackupInfo;
|
||||
IQuery* q_setVirtualMainClient;
|
||||
//@-SQLGenVariablesEnd
|
||||
|
||||
IDatabase *db;
|
||||
|
||||
@ -1398,6 +1398,17 @@ bool upgrade40_41()
|
||||
return b;
|
||||
}
|
||||
|
||||
bool upgrade41_42()
|
||||
{
|
||||
IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
||||
|
||||
bool b = true;
|
||||
|
||||
b &= db->Write("ALTER TABLE clients ADD virtualmain TEXT");
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void upgrade(void)
|
||||
{
|
||||
@ -1420,7 +1431,7 @@ void upgrade(void)
|
||||
|
||||
int ver=watoi(res_v[0][L"tvalue"]);
|
||||
int old_v;
|
||||
int max_v=41;
|
||||
int max_v=42;
|
||||
{
|
||||
IScopedLock lock(startup_status.mutex);
|
||||
startup_status.target_db_version=max_v;
|
||||
@ -1637,6 +1648,12 @@ void upgrade(void)
|
||||
has_error=true;
|
||||
}
|
||||
++ver;
|
||||
case 41:
|
||||
if(!upgrade41_42())
|
||||
{
|
||||
has_error=true;
|
||||
}
|
||||
++ver;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -15,9 +15,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef CLIENT_ONLY
|
||||
|
||||
#include "server.h"
|
||||
#include "../Interface/Server.h"
|
||||
#include "../Interface/Database.h"
|
||||
@ -46,6 +43,8 @@ bool BackupServer::filesystem_transactions_enabled = false;
|
||||
volatile bool BackupServer::update_delete_pending_clients=true;
|
||||
IMutex* BackupServer::force_offline_mutex=NULL;
|
||||
std::vector<std::wstring> BackupServer::force_offline_clients;
|
||||
std::map<std::wstring, std::vector<std::wstring> > BackupServer::virtual_clients;
|
||||
IMutex* BackupServer::virtual_clients_mutex=NULL;
|
||||
|
||||
|
||||
BackupServer::BackupServer(IPipe *pExitpipe)
|
||||
@ -54,6 +53,7 @@ BackupServer::BackupServer(IPipe *pExitpipe)
|
||||
throttle_mutex=Server->createMutex();
|
||||
exitpipe=pExitpipe;
|
||||
force_offline_mutex=Server->createMutex();
|
||||
virtual_clients_mutex=Server->createMutex();
|
||||
|
||||
if(Server->getServerParameter("internet_only_mode")=="true")
|
||||
internet_only_mode=true;
|
||||
@ -65,6 +65,7 @@ BackupServer::~BackupServer()
|
||||
{
|
||||
Server->destroy(throttle_mutex);
|
||||
Server->destroy(force_offline_mutex);
|
||||
Server->destroy(virtual_clients_mutex);
|
||||
}
|
||||
|
||||
void BackupServer::operator()(void)
|
||||
@ -218,59 +219,116 @@ void BackupServer::findClients(FileClient &fc)
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct SClientInfo
|
||||
{
|
||||
explicit SClientInfo(std::wstring name)
|
||||
: name(name), internetclient(false), delete_pending(false),
|
||||
filebackup_group_offset(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SClientInfo() :
|
||||
internetclient(false), delete_pending(false),
|
||||
filebackup_group_offset(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool operator==(const SClientInfo& other) const
|
||||
{
|
||||
return name==other.name;
|
||||
}
|
||||
|
||||
std::wstring name;
|
||||
std::wstring subname;
|
||||
std::wstring mainname;
|
||||
sockaddr_in addr;
|
||||
std::string endpoint_name;
|
||||
bool internetclient;
|
||||
bool delete_pending;
|
||||
int filebackup_group_offset;
|
||||
};
|
||||
}
|
||||
|
||||
void BackupServer::startClients(FileClient &fc)
|
||||
{
|
||||
std::vector<std::wstring> names;
|
||||
std::vector<sockaddr_in> servers;
|
||||
std::vector<std::string> endpoint_names;
|
||||
std::vector<SClientInfo> client_info;
|
||||
|
||||
if(!internet_only_mode)
|
||||
{
|
||||
names=fc.getServerNames();
|
||||
servers=fc.getServers();
|
||||
std::vector<std::wstring> names=fc.getServerNames();
|
||||
std::vector<sockaddr_in> servers=fc.getServers();
|
||||
|
||||
client_info.resize(servers.size());
|
||||
|
||||
for(size_t i=0;i<names.size();++i)
|
||||
{
|
||||
client_info[i].name = names[i];
|
||||
client_info[i].addr = servers[i];
|
||||
}
|
||||
}
|
||||
|
||||
endpoint_names.resize(servers.size());
|
||||
|
||||
maybeUpdateExistingClientsLower();
|
||||
|
||||
for(size_t i=0;i<names.size();++i)
|
||||
{
|
||||
names[i]=Server->ConvertToUnicode(conv_filename(Server->ConvertToUTF8(names[i])));
|
||||
|
||||
fixClientnameCase(names[i]);
|
||||
}
|
||||
|
||||
std::vector<bool> inetclient;
|
||||
inetclient.resize(names.size());
|
||||
std::fill(inetclient.begin(), inetclient.end(), false);
|
||||
std::vector<std::pair<std::string, std::string> > anames=InternetServiceConnector::getOnlineClients();
|
||||
for(size_t i=0;i<anames.size();++i)
|
||||
{
|
||||
std::wstring new_name=Server->ConvertToUnicode(conv_filename(anames[i].first));
|
||||
bool skip=false;
|
||||
for(size_t j=0;j<names.size();++j)
|
||||
std::wstring new_name = Server->ConvertToUnicode(anames[i].first);
|
||||
if(std::find(client_info.begin(), client_info.end(), SClientInfo(new_name))!=client_info.end())
|
||||
{
|
||||
if( new_name==names[j] )
|
||||
{
|
||||
skip=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(skip)
|
||||
continue;
|
||||
}
|
||||
|
||||
fixClientnameCase(new_name);
|
||||
names.push_back(new_name);
|
||||
inetclient.push_back(true);
|
||||
sockaddr_in n;
|
||||
memset(&n, 0, sizeof(sockaddr_in));
|
||||
servers.push_back(n);
|
||||
endpoint_names.push_back(anames[i].second);
|
||||
SClientInfo new_client;
|
||||
new_client.name = new_name;
|
||||
memset(&(new_client.addr), 0, sizeof(sockaddr_in));
|
||||
new_client.endpoint_name = anames[i].second;
|
||||
new_client.internetclient = true;
|
||||
|
||||
client_info.push_back(new_client);
|
||||
}
|
||||
|
||||
for(size_t i=0;i<client_info.size();++i)
|
||||
{
|
||||
client_info[i].name=Server->ConvertToUnicode(conv_filename(Server->ConvertToUTF8(client_info[i].name)));
|
||||
|
||||
fixClientnameCase(client_info[i].name);
|
||||
|
||||
client_info[i].mainname=client_info[i].name;
|
||||
}
|
||||
|
||||
{
|
||||
IScopedLock lock(virtual_clients_mutex);
|
||||
|
||||
for(size_t i=0,size=client_info.size();i<size;++i)
|
||||
{
|
||||
std::map<std::wstring, std::vector<std::wstring> >::iterator it=virtual_clients.find(client_info[i].name);
|
||||
|
||||
if(it!=virtual_clients.end())
|
||||
{
|
||||
for(size_t j=0;j<it->second.size();++j)
|
||||
{
|
||||
std::wstring new_name = client_info[i].name+L"["+it->second[j]+L"]";
|
||||
|
||||
new_name = Server->ConvertToUnicode(conv_filename(Server->ConvertToUTF8(new_name)));
|
||||
|
||||
fixClientnameCase(new_name);
|
||||
|
||||
SClientInfo new_client = client_info[i];
|
||||
new_client.name = new_name;
|
||||
new_client.mainname = client_info[i].name;
|
||||
new_client.subname = it->second[j];
|
||||
new_client.filebackup_group_offset = static_cast<int>((j+1)*c_group_size);
|
||||
|
||||
client_info.push_back(new_client);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<bool> delete_pending_curr;
|
||||
delete_pending_curr.resize(names.size());
|
||||
maybeUpdateDeletePendingClients();
|
||||
|
||||
std::vector<std::wstring> local_force_offline_clients;
|
||||
@ -279,20 +337,23 @@ void BackupServer::startClients(FileClient &fc)
|
||||
local_force_offline_clients = force_offline_clients;
|
||||
}
|
||||
|
||||
for(size_t i=0;i<names.size();++i)
|
||||
for(size_t i=0;i<client_info.size();++i)
|
||||
{
|
||||
delete_pending_curr[i]=isDeletePendingClient(names[i]);
|
||||
delete_pending_curr[i] = delete_pending_curr[i] ||
|
||||
std::find(local_force_offline_clients.begin(), local_force_offline_clients.end(), names[i]) != local_force_offline_clients.end();
|
||||
SClientInfo& curr_info = client_info[i];
|
||||
curr_info.delete_pending=isDeletePendingClient(curr_info.name);
|
||||
curr_info.delete_pending = curr_info.delete_pending ||
|
||||
std::find(local_force_offline_clients.begin(), local_force_offline_clients.end(), curr_info.name) != local_force_offline_clients.end();
|
||||
|
||||
if(delete_pending_curr[i])
|
||||
if(curr_info.delete_pending)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::map<std::wstring, SClient>::iterator it=clients.find(names[i]);
|
||||
std::map<std::wstring, SClient>::iterator it=clients.find(curr_info.name);
|
||||
if( it==clients.end() )
|
||||
{
|
||||
Server->Log(L"New Backupclient: "+names[i]);
|
||||
ServerStatus::setOnline(names[i], true);
|
||||
Server->Log(L"New Backupclient: "+curr_info.name);
|
||||
ServerStatus::setOnline(curr_info.name, true);
|
||||
IPipe *np=Server->createMemoryPipe();
|
||||
|
||||
update_existing_client_names=true;
|
||||
@ -302,44 +363,46 @@ void BackupServer::startClients(FileClient &fc)
|
||||
if(snapshots_enabled)
|
||||
use_reflink=true;
|
||||
#endif
|
||||
ClientMain *client=new ClientMain(np, servers[i], names[i], inetclient[i], snapshots_enabled, use_reflink);
|
||||
ClientMain *client=new ClientMain(np, curr_info.addr, curr_info.name, curr_info.subname, curr_info.mainname,
|
||||
curr_info.filebackup_group_offset, curr_info.internetclient, snapshots_enabled, use_reflink);
|
||||
Server->getThreadPool()->execute(client);
|
||||
|
||||
SClient c;
|
||||
c.pipe=np;
|
||||
c.offlinecount=0;
|
||||
c.addr=servers[i];
|
||||
c.internet_connection=inetclient[i];
|
||||
c.addr=curr_info.addr;
|
||||
c.internet_connection=curr_info.internetclient;
|
||||
|
||||
if(c.internet_connection)
|
||||
{
|
||||
ServerStatus::setIP(names[i], inet_addr(endpoint_names[i].c_str()));
|
||||
ServerStatus::setIP(curr_info.name, inet_addr(curr_info.endpoint_name.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerStatus::setIP(names[i], c.addr.sin_addr.s_addr);
|
||||
ServerStatus::setIP(curr_info.name, c.addr.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
clients.insert(std::pair<std::wstring, SClient>(names[i], c) );
|
||||
clients.insert(std::pair<std::wstring, SClient>(curr_info.name, c) );
|
||||
}
|
||||
else if(it->second.offlinecount<max_offline)
|
||||
{
|
||||
bool found_lan=false;
|
||||
if(inetclient[i]==false && it->second.internet_connection==true)
|
||||
if(!curr_info.internetclient && it->second.internet_connection)
|
||||
{
|
||||
found_lan=true;
|
||||
}
|
||||
|
||||
if(it->second.addr.sin_addr.s_addr==servers[i].sin_addr.s_addr && !found_lan)
|
||||
if(it->second.addr.sin_addr.s_addr==curr_info.addr.sin_addr.s_addr && !found_lan)
|
||||
{
|
||||
it->second.offlinecount=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool none_fits=true;
|
||||
for(size_t j=0;j<names.size();++j)
|
||||
for(size_t j=0;j<client_info.size();++j)
|
||||
{
|
||||
if(i!=j && names[j]==names[i] && it->second.addr.sin_addr.s_addr==servers[j].sin_addr.s_addr)
|
||||
if(i!=j && client_info[j].name==curr_info.name
|
||||
&& it->second.addr.sin_addr.s_addr==client_info[j].addr.sin_addr.s_addr)
|
||||
{
|
||||
none_fits=false;
|
||||
break;
|
||||
@ -347,28 +410,23 @@ void BackupServer::startClients(FileClient &fc)
|
||||
}
|
||||
if(none_fits || found_lan)
|
||||
{
|
||||
it->second.addr=servers[i];
|
||||
it->second.internet_connection=inetclient[i];
|
||||
it->second.addr=curr_info.addr;
|
||||
it->second.internet_connection=curr_info.internetclient;
|
||||
std::string msg;
|
||||
msg.resize(7+sizeof(sockaddr_in)+1);
|
||||
msg[0]='a'; msg[1]='d'; msg[2]='d'; msg[3]='r'; msg[4]='e'; msg[5]='s'; msg[6]='s';
|
||||
memcpy(&msg[7], &it->second.addr, sizeof(sockaddr_in));
|
||||
msg[7+sizeof(sockaddr_in)]=(inetclient[i]==true?1:0);
|
||||
msg[7+sizeof(sockaddr_in)]=(curr_info.internetclient?1:0);
|
||||
it->second.pipe->Write(msg);
|
||||
|
||||
char *ip=(char*)&it->second.addr.sin_addr.s_addr;
|
||||
|
||||
Server->Log("New client address: "+nconvert((unsigned char)ip[0])+"."+nconvert((unsigned char)ip[1])+"."+nconvert((unsigned char)ip[2])+"."+nconvert((unsigned char)ip[3]), LL_INFO);
|
||||
|
||||
ServerStatus::setIP(names[i], it->second.addr.sin_addr.s_addr);
|
||||
ServerStatus::setIP(curr_info.name, it->second.addr.sin_addr.s_addr);
|
||||
|
||||
it->second.offlinecount=0;
|
||||
}
|
||||
/*else if(found_lan)
|
||||
{
|
||||
force_offline_clients.push_back(names[i]);
|
||||
it->second.offlinecount=max_offline;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -383,12 +441,12 @@ void BackupServer::startClients(FileClient &fc)
|
||||
for(std::map<std::wstring, SClient>::iterator it=clients.begin();it!=clients.end();++it)
|
||||
{
|
||||
bool found=false;
|
||||
for(size_t i=0;i<names.size();++i)
|
||||
for(size_t i=0;i<client_info.size();++i)
|
||||
{
|
||||
if(delete_pending_curr[i])
|
||||
if(client_info[i].delete_pending)
|
||||
continue;
|
||||
|
||||
if( it->first==names[i] )
|
||||
if( it->first==client_info[i].name )
|
||||
{
|
||||
found=true;
|
||||
break;
|
||||
@ -420,6 +478,16 @@ void BackupServer::startClients(FileClient &fc)
|
||||
ServerStatus::removeStatus(it->first);
|
||||
Server->destroy(it->second.pipe);
|
||||
|
||||
{
|
||||
IScopedLock lock(virtual_clients_mutex);
|
||||
|
||||
std::map<std::wstring, std::vector<std::wstring> >::iterator virt_it=virtual_clients.find(it->first);
|
||||
if(virt_it!=virtual_clients.end())
|
||||
{
|
||||
virtual_clients.erase(virt_it);
|
||||
}
|
||||
}
|
||||
|
||||
IScopedLock lock(force_offline_mutex);
|
||||
std::vector<std::wstring>::iterator off_iter = std::find(force_offline_clients.begin(),
|
||||
force_offline_clients.end(),
|
||||
@ -718,5 +786,13 @@ void BackupServer::fixClientnameCase( std::wstring& clientname )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //CLIENT_ONLY
|
||||
|
||||
void BackupServer::setVirtualClients( const std::wstring& clientname, const std::wstring& new_virtual_clients )
|
||||
{
|
||||
std::vector<std::wstring> toks;
|
||||
TokenizeMail(new_virtual_clients, toks, L"|");
|
||||
|
||||
IScopedLock lock(virtual_clients_mutex);
|
||||
virtual_clients[clientname] = toks;
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,8 @@ public:
|
||||
|
||||
static void forceOfflineClient(const std::wstring& clientname);
|
||||
|
||||
static void setVirtualClients(const std::wstring& clientname, const std::wstring& virtual_clients);
|
||||
|
||||
private:
|
||||
void findClients(FileClient &fc);
|
||||
void startClients(FileClient &fc);
|
||||
@ -77,6 +79,9 @@ private:
|
||||
|
||||
static IMutex* force_offline_mutex;
|
||||
static std::vector<std::wstring> force_offline_clients;
|
||||
|
||||
static IMutex* virtual_clients_mutex;
|
||||
static std::map<std::wstring, std::vector<std::wstring> > virtual_clients;
|
||||
};
|
||||
|
||||
#endif //URB_SERVER_H
|
||||
|
||||
@ -395,6 +395,8 @@ void ServerSettings::readSettingsClient(void)
|
||||
std::wstring swtmp=settings_client->getValue(L"computername", L"");
|
||||
if(!swtmp.empty())
|
||||
settings->computername=swtmp;
|
||||
if(settings_client->getValue(L"virtual_clients", &swtmp))
|
||||
settings->virtual_clients=swtmp;
|
||||
if(settings_client->getValue(L"exclude_files", &swtmp))
|
||||
settings->exclude_files=swtmp;
|
||||
if(settings_client->getValue(L"include_files", &swtmp))
|
||||
|
||||
@ -51,6 +51,7 @@ struct SSettings
|
||||
std::string backup_window_incr_image;
|
||||
std::string backup_window_full_image;
|
||||
std::wstring computername;
|
||||
std::wstring virtual_clients;
|
||||
std::wstring exclude_files;
|
||||
std::wstring include_files;
|
||||
std::wstring default_dirs;
|
||||
|
||||
@ -358,6 +358,27 @@ void ServerStatus::setClientId( const std::wstring &clientname, int clientid)
|
||||
SStatus *s=&status[clientname];
|
||||
s->clientid = clientid;
|
||||
}
|
||||
|
||||
void ServerStatus::addRunningJob( const std::wstring &clientname )
|
||||
{
|
||||
IScopedLock lock(mutex);
|
||||
SStatus *s=&status[clientname];
|
||||
s->running_jobs+=1;
|
||||
}
|
||||
|
||||
void ServerStatus::subRunningJob( const std::wstring &clientname )
|
||||
{
|
||||
IScopedLock lock(mutex);
|
||||
SStatus *s=&status[clientname];
|
||||
s->running_jobs-=1;
|
||||
}
|
||||
|
||||
int ServerStatus::numRunningJobs( const std::wstring &clientname )
|
||||
{
|
||||
IScopedLock lock(mutex);
|
||||
SStatus *s=&status[clientname];
|
||||
return s->running_jobs;
|
||||
}
|
||||
|
||||
ACTION_IMPL(server_status)
|
||||
{
|
||||
|
||||
@ -62,7 +62,7 @@ struct SProcess
|
||||
struct SStatus
|
||||
{
|
||||
SStatus(void){ online=false; has_status=false;r_online=false; clientid=0;
|
||||
comm_pipe=NULL; status_error=se_none; ; }
|
||||
comm_pipe=NULL; status_error=se_none; running_jobs=0; }
|
||||
|
||||
std::wstring client;
|
||||
int clientid;
|
||||
@ -75,6 +75,7 @@ struct SStatus
|
||||
std::string client_version_string;
|
||||
std::string os_version_string;
|
||||
std::vector<SProcess> processes;
|
||||
int running_jobs;
|
||||
};
|
||||
|
||||
class ServerStatus
|
||||
@ -131,6 +132,12 @@ public:
|
||||
static void setProcessPcDone(const std::wstring &clientname, size_t id,
|
||||
int pcdone);
|
||||
|
||||
static void addRunningJob(const std::wstring &clientname);
|
||||
|
||||
static void subRunningJob(const std::wstring &clientname);
|
||||
|
||||
static int numRunningJobs(const std::wstring &clientname);
|
||||
|
||||
static SProcess getProcess(const std::wstring &clientname, size_t id);
|
||||
|
||||
private:
|
||||
|
||||
@ -111,6 +111,7 @@ JSON::Object getJSONClientSettings(ServerSettings &settings)
|
||||
SET_SETTING(backup_window_incr_image);
|
||||
SET_SETTING(backup_window_full_image);
|
||||
SET_SETTING(computername);
|
||||
SET_SETTING(virtual_clients);
|
||||
SET_SETTING(exclude_files);
|
||||
SET_SETTING(include_files);
|
||||
SET_SETTING(default_dirs);
|
||||
@ -772,6 +773,7 @@ ACTION_IMPL(settings)
|
||||
s=getClientSettings(db, t_clientid);
|
||||
obj.set("overwrite", s.overwrite);
|
||||
obj.set("clientid", t_clientid);
|
||||
obj.set("main_client", backupdao.getVirtualMainClientname(t_clientid).value.empty());
|
||||
|
||||
ret.set("cowraw_available", BackupServer::isSnapshotsEnabled());
|
||||
ret.set("settings", obj);
|
||||
|
||||
@ -222,7 +222,8 @@ ACTION_IMPL(status)
|
||||
{
|
||||
for(size_t i=0;i<remove_client.size();++i)
|
||||
{
|
||||
IQuery *q=db->Prepare("UPDATE clients SET delete_pending=1 WHERE id=?");
|
||||
IQuery *q=db->Prepare("UPDATE clients SET delete_pending=1 WHERE id=? OR virtualmain = (SELECT name FROM clients WHERE id=?)");
|
||||
q->Bind(remove_client[i]);
|
||||
q->Bind(remove_client[i]);
|
||||
q->Write();
|
||||
q->Reset();
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1809,6 +1809,8 @@ function show_settings2(data)
|
||||
data.settings.global_settings_start="";
|
||||
data.settings.global_settings_end="";
|
||||
|
||||
data.settings.main_client = true;
|
||||
|
||||
data.settings.client_plural="s";
|
||||
|
||||
data.settings.ONLY_WIN32_BEGIN=unescapeHTML(data.settings.ONLY_WIN32_BEGIN);
|
||||
@ -2191,6 +2193,7 @@ g.settings_list=[
|
||||
"internet_mode_enabled",
|
||||
"silent_update",
|
||||
"client_quota",
|
||||
"virtual_clients",
|
||||
"end_to_end_file_backup_verification",
|
||||
"local_full_file_transfer_mode",
|
||||
"internet_full_file_transfer_mode",
|
||||
|
||||
@ -565,7 +565,7 @@ function validate_text_int(a)
|
||||
{
|
||||
for(var i=0;i<a.length;++i)
|
||||
{
|
||||
if(!isInt(I(a[i]).value))
|
||||
if(I(a[i]) && !isInt(I(a[i]).value))
|
||||
{
|
||||
if(trans("validate_err_notint_"+a[i]))
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -162,6 +162,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{?main_client}
|
||||
<div class="tab-pane" id="permissions">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
@ -224,11 +225,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/main_client}
|
||||
|
||||
<div class="tab-pane" id="client">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<form class="form-horizontal" role="form">
|
||||
{?main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="startup_backup_delay">{tDelay after system startup}:</label>
|
||||
<div class="col-sm-6">
|
||||
@ -238,6 +241,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{tBackup window}</label>
|
||||
<div class="col-sm-6">
|
||||
@ -283,14 +287,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{?main_client}
|
||||
{no_compname_start|s}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="computername">{tComputer name}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="computername" value="{computername|s}"/>
|
||||
<input type="text" class="form-control" id="computername" value="{computername}"/>
|
||||
</div>
|
||||
</div>
|
||||
{no_compname_end|s}
|
||||
{/main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="local_speed">{tMax backup speed for local network}:</label>
|
||||
<div class="col-sm-6">
|
||||
@ -300,18 +306,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{?main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="silent_update">{tPerform autoupdates silently}:</label>
|
||||
<div class="col-sm-6">
|
||||
<label><input type="checkbox" id="silent_update" {silent_update}/></label>
|
||||
</div>
|
||||
</div>
|
||||
{/main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="client_quota">{tSoft client quota}:</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="client_quota" value="{client_quota}"/>
|
||||
</div>
|
||||
</div>
|
||||
{?main_client}
|
||||
{no_compname_start|s}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="virtual_clients">{tVirtual sub client names}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control" id="virtual_clients" value="{virtual_clients}"/>
|
||||
</div>
|
||||
</div>
|
||||
{no_compname_end|s}
|
||||
{/main_client}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -399,6 +417,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{global_settings_end_inet|s}
|
||||
{?main_client}
|
||||
{no_compname_start_inet|s}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="internet_mode_enabled">{tEnable internet mode}:</label>
|
||||
@ -413,6 +432,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{no_compname_end_inet|s}
|
||||
{/main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="internet_image_backups">{tDo image backups over internet}:</label>
|
||||
<div class="col-sm-6">
|
||||
@ -445,6 +465,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{global_settings_end_inet|s}
|
||||
{?main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="internet_encrypt">{tEncrypted transfer}:</label>
|
||||
<div class="col-sm-6">
|
||||
@ -457,18 +478,21 @@
|
||||
<label><input type="checkbox" id="internet_compress" value="false" {internet_compress}/></label>
|
||||
</div>
|
||||
</div>
|
||||
{/main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="internet_calculate_filehashes_on_client">{tCalculate file-hashes on the client}:</label>
|
||||
<div class="col-sm-6">
|
||||
<label><input type="checkbox" id="internet_calculate_filehashes_on_client" value="false" {internet_calculate_filehashes_on_client}/></label>
|
||||
</div>
|
||||
</div>
|
||||
{?main_client}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="internet_connect_always">{tConnect to Internet backup server if connected to local backup server}:</label>
|
||||
<div class="col-sm-6">
|
||||
<label><input type="checkbox" id="internet_connect_always" value="false" {internet_connect_always}/></label>
|
||||
</div>
|
||||
</div>
|
||||
{/main_client}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -582,10 +606,6 @@
|
||||
<div class="col-sm-6">
|
||||
<label><input type="checkbox" id="end_to_end_file_backup_verification" value="false" {end_to_end_file_backup_verification}/></label>
|
||||
</div>
|
||||
<tr>
|
||||
<td>{tFollow symbolic links on Linux}:</td>
|
||||
<td><input type="checkbox" id="follow_symlinks" value="true" {follow_symlinks}/></td>
|
||||
</tr>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="verify_using_client_hashes">{tVerify file backups using client side hashes}:</label>
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
<ul class="nav nav-pills" id="settings_tabber" data-tabs="tabs">
|
||||
<li class="active"><a href="#file_backups" data-toggle="tab">{tFile Backups}</a></li>
|
||||
<li><a href="#image_backups" data-toggle="tab">{tImage Backups}</a></li>
|
||||
{?main_client}
|
||||
<li><a href="#permissions" data-toggle="tab">{tPermissions}</a></li>
|
||||
{/main_client}
|
||||
<li><a href="#client" data-toggle="tab">{tClient}</a></li>
|
||||
<li><a href="#archive" data-toggle="tab">{tArchive}</a></li>
|
||||
{internet_settings_start|s}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user