backup-daemon:本地系统备份逻辑基本完成
This commit is contained in:
parent
46d4c5c38a
commit
dba7168325
|
@ -7,6 +7,9 @@ CONFIG -= app_bundle
|
||||||
|
|
||||||
CONFIG += link_pkgconfig
|
CONFIG += link_pkgconfig
|
||||||
|
|
||||||
|
LIBS += -lblkid \
|
||||||
|
-lkysec
|
||||||
|
|
||||||
# The following define makes your compiler emit warnings if you use
|
# The following define makes your compiler emit warnings if you use
|
||||||
# any Qt feature that has been marked deprecated (the exact warnings
|
# any Qt feature that has been marked deprecated (the exact warnings
|
||||||
# depend on your compiler). Please consult the documentation of the
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
|
|
@ -55,6 +55,13 @@ class ManagerAdaptor: public QDBusAbstractAdaptor
|
||||||
" <signal name=\"sendGhostBackupResult\">\n"
|
" <signal name=\"sendGhostBackupResult\">\n"
|
||||||
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\n"
|
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\n"
|
||||||
" </signal>\n"
|
" </signal>\n"
|
||||||
|
" <signal name=\"backupFinished\">\n"
|
||||||
|
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\n"
|
||||||
|
" </signal>\n"
|
||||||
|
" <signal name=\"progress\">\n"
|
||||||
|
" <arg direction=\"out\" type=\"i\"/>\n"
|
||||||
|
" <arg direction=\"out\" type=\"i\"/>\n"
|
||||||
|
" </signal>\n"
|
||||||
" <method name=\"Mount_backup_partition\">\n"
|
" <method name=\"Mount_backup_partition\">\n"
|
||||||
" <arg direction=\"out\" type=\"i\"/>\n"
|
" <arg direction=\"out\" type=\"i\"/>\n"
|
||||||
" </method>\n"
|
" </method>\n"
|
||||||
|
@ -122,6 +129,8 @@ public Q_SLOTS: // METHODS
|
||||||
int goRestore(BackupWrapper backupWrapper);
|
int goRestore(BackupWrapper backupWrapper);
|
||||||
int cancel(BackupWrapper backupWrapper);
|
int cancel(BackupWrapper backupWrapper);
|
||||||
Q_SIGNALS: // SIGNALS
|
Q_SIGNALS: // SIGNALS
|
||||||
|
void backupFinished(bool result);
|
||||||
|
void progress(int in0, int in1);
|
||||||
void sendBackupResult(bool result);
|
void sendBackupResult(bool result);
|
||||||
void sendDeleteResult(bool result);
|
void sendDeleteResult(bool result);
|
||||||
void sendEnvCheckResult(int result);
|
void sendEnvCheckResult(int result);
|
||||||
|
|
|
@ -30,9 +30,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
qDebug() << QString("测试 begin");
|
qDebug() << QString("测试 begin");
|
||||||
BackupWrapper backupWrapper;
|
BackupWrapper backupWrapper;
|
||||||
|
backupWrapper.m_backupName = "赵民勇test";
|
||||||
backupWrapper.m_backupExcludePaths = Utils::getFromExcludePathsFile();
|
backupWrapper.m_backupExcludePaths = Utils::getFromExcludePathsFile();
|
||||||
MyBackupManager manager;
|
MyBackupManager manager;
|
||||||
manager.checkEnv(backupWrapper);
|
manager.goBackup(backupWrapper);
|
||||||
|
|
||||||
qDebug() << QString("测试 end");
|
qDebug() << QString("测试 end");
|
||||||
// test end
|
// test end
|
||||||
|
|
|
@ -95,6 +95,9 @@ int MyBackupManager::goBackup(const BackupWrapper& backupWrapper)
|
||||||
this->finished();
|
this->finished();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(worker, &Worker::progress, this, [&](int rate) {
|
||||||
|
emit this->progress(int(BackupState::WORKING), rate);
|
||||||
|
});
|
||||||
connect(worker, &Worker::workResult, this, [&] (bool result) {
|
connect(worker, &Worker::workResult, this, [&] (bool result) {
|
||||||
emit this->sendBackupResult(result);
|
emit this->sendBackupResult(result);
|
||||||
this->finished();
|
this->finished();
|
||||||
|
@ -187,6 +190,7 @@ int MyBackupManager::getBackupState(bool& isActive)
|
||||||
*/
|
*/
|
||||||
int MyBackupManager::cancel(const BackupWrapper& backupWrapper)
|
int MyBackupManager::cancel(const BackupWrapper& backupWrapper)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(backupWrapper)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,21 @@ public:
|
||||||
virtual ~MyBackupManager();
|
virtual ~MyBackupManager();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// 环境检查结果信号
|
// 这3个信号供控制面板/自动更新等外围模块使用
|
||||||
void sendEnvCheckResult(int result);
|
|
||||||
// 开始备份结果信号
|
// 开始备份结果信号
|
||||||
void sendStartBackupResult(int result);
|
void sendStartBackupResult(int result);
|
||||||
// 备份结果信号
|
// 备份结果信号
|
||||||
void sendBackupResult(bool result);
|
void sendBackupResult(bool result);
|
||||||
// 进度信号
|
// 进度信号
|
||||||
void sendRate(int, int);
|
void sendRate(int, int);
|
||||||
|
|
||||||
|
// 模块内使用的信号
|
||||||
|
// 进度信号
|
||||||
|
void progress(int, int);
|
||||||
|
// 备份结果信号
|
||||||
|
void backupFinished(bool result);
|
||||||
|
// 环境检查结果信号
|
||||||
|
void sendEnvCheckResult(int result);
|
||||||
// 还原结果信号
|
// 还原结果信号
|
||||||
void sendRestoreResult(bool result);
|
void sendRestoreResult(bool result);
|
||||||
// 删除备份结果信号
|
// 删除备份结果信号
|
||||||
|
|
|
@ -15,6 +15,7 @@ CalcBackupSize::CalcBackupSize(QObject* parent) :
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_process, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
connect(m_process, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
||||||
|
Q_UNUSED(error)
|
||||||
m_process->kill();
|
m_process->kill();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -89,7 +90,6 @@ void CalcBackupSize::parseResult()
|
||||||
QString out(m_process->readAll());
|
QString out(m_process->readAll());
|
||||||
QStringList lines = out.split("\n");
|
QStringList lines = out.split("\n");
|
||||||
for (QString& line : lines) {
|
for (QString& line : lines) {
|
||||||
line.trimmed();
|
|
||||||
// 获取文件夹数目
|
// 获取文件夹数目
|
||||||
// if (line.startsWith("Number of files:")) {
|
// if (line.startsWith("Number of files:")) {
|
||||||
// int indexOfDir = line.indexOf("dir: ");
|
// int indexOfDir = line.indexOf("dir: ");
|
||||||
|
@ -102,7 +102,7 @@ void CalcBackupSize::parseResult()
|
||||||
// m_size += numOfDirs * 4096;
|
// m_size += numOfDirs * 4096;
|
||||||
// }
|
// }
|
||||||
if (line.startsWith("Total transferred file size: ")) {
|
if (line.startsWith("Total transferred file size: ")) {
|
||||||
m_size += line.replace("Total file size:", "").replace("bytes", "").replace(",","").trimmed().toLongLong();
|
m_size += line.replace("Total transferred file size: ", "").replace("bytes", "").replace(",","").trimmed().toLongLong();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,7 @@ void CalcBackupSize::parseResult()
|
||||||
void CalcBackupSize::processFinish(int exitCode, QProcess::ExitStatus)
|
void CalcBackupSize::processFinish(int exitCode, QProcess::ExitStatus)
|
||||||
{
|
{
|
||||||
qDebug() << "CalcBackupSize::getCalcResult invoke begin";
|
qDebug() << "CalcBackupSize::getCalcResult invoke begin";
|
||||||
|
Q_UNUSED(exitCode)
|
||||||
|
|
||||||
parseResult();
|
parseResult();
|
||||||
emit finished(m_size);
|
emit finished(m_size);
|
||||||
|
|
|
@ -29,6 +29,7 @@ RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_p, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
connect(m_p, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
||||||
|
Q_UNUSED(error)
|
||||||
m_p->kill();
|
m_p->kill();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -301,15 +301,15 @@ void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPo
|
||||||
* @param backupPoint, BackupPoint
|
* @param backupPoint, BackupPoint
|
||||||
* @param node, QDomElement
|
* @param node, QDomElement
|
||||||
*/
|
*/
|
||||||
void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, QDomElement& node)
|
void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, QDomDocument& doc, QDomNode& node)
|
||||||
{
|
{
|
||||||
node.appendChild(createTextElement(COMMENT, backupPoint.m_backupName));
|
node.appendChild(createTextElement(doc, COMMENT, backupPoint.m_backupName));
|
||||||
node.appendChild(createTextElement(TIME, backupPoint.m_time));
|
node.appendChild(createTextElement(doc, TIME, backupPoint.m_time));
|
||||||
node.appendChild(createTextElement(UUID, backupPoint.m_uuid));
|
node.appendChild(createTextElement(doc, UUID, backupPoint.m_uuid));
|
||||||
node.appendChild(createTextElement(SIZE, backupPoint.m_size));
|
node.appendChild(createTextElement(doc, SIZE, backupPoint.m_size));
|
||||||
node.appendChild(createTextElement(STATE, backupPoint.m_state));
|
node.appendChild(createTextElement(doc, STATE, backupPoint.m_state));
|
||||||
node.appendChild(createTextElement(TYPE, QString::number(backupPoint.m_type)));
|
node.appendChild(createTextElement(doc, TYPE, QString::number(backupPoint.m_type)));
|
||||||
node.appendChild(createTextElement(POSITION, QString::number(backupPoint.m_iPosition)));
|
node.appendChild(createTextElement(doc, POSITION, QString::number(backupPoint.m_iPosition)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -318,13 +318,79 @@ void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, Q
|
||||||
* @param text
|
* @param text
|
||||||
* @return <tagName>text</tagName>
|
* @return <tagName>text</tagName>
|
||||||
*/
|
*/
|
||||||
QDomElement ParseBackupList::createTextElement(const QString& tagName, const QString& text)
|
QDomElement ParseBackupList::createTextElement(QDomDocument& doc, const QString& tagName, const QString& text)
|
||||||
{
|
{
|
||||||
QDomElement node;
|
QDomElement node = doc.createElement(tagName);
|
||||||
node.setTagName(tagName);
|
QDomText textNode = doc.createTextNode(text);
|
||||||
QDomText textNode;
|
|
||||||
textNode.setData(text);
|
|
||||||
node.appendChild(textNode);
|
node.appendChild(textNode);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 新增备份节点
|
||||||
|
* @param backupPoint, 备份点信息
|
||||||
|
* @return SUCCESS成功; XML_PARSE_ERR失败
|
||||||
|
*/
|
||||||
|
ParseBackupList::ParseResult ParseBackupList::addItem(const BackupPoint& backupPoint)
|
||||||
|
{
|
||||||
|
QDomDocument doc;
|
||||||
|
if (!Doc_setContent(doc))
|
||||||
|
return XML_PARSE_ERR;
|
||||||
|
|
||||||
|
QDomElement backupPointNode = doc.createElement(BACKUPPOINT);
|
||||||
|
backupPointToElementNode(backupPoint, doc, backupPointNode);
|
||||||
|
|
||||||
|
QDomElement root = doc.documentElement();
|
||||||
|
root.appendChild(backupPointNode);
|
||||||
|
|
||||||
|
QFile xmlFile(m_xmlPath);
|
||||||
|
if (!xmlFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
QTextStream out(&xmlFile);
|
||||||
|
doc.save(out, QDomNode::NodeType::CDATASectionNode);
|
||||||
|
xmlFile.close();
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新备份点信息
|
||||||
|
* @param backupPoint,新的备份点信息
|
||||||
|
* @return SUCCESS成功; XML_PARSE_ERR失败
|
||||||
|
*/
|
||||||
|
ParseBackupList::ParseResult ParseBackupList::updateItem(const BackupPoint & backupPoint)
|
||||||
|
{
|
||||||
|
QDomDocument doc;
|
||||||
|
if (!Doc_setContent(doc))
|
||||||
|
return XML_PARSE_ERR;
|
||||||
|
|
||||||
|
QDomElement root = doc.documentElement();
|
||||||
|
QDomNodeList list = root.childNodes();
|
||||||
|
|
||||||
|
for (int i = 0; i < list.count(); i++) {
|
||||||
|
QDomNode node = list.at(i);
|
||||||
|
if (!node.isElement())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QDomElement eleUuid = node.firstChildElement(UUID);
|
||||||
|
if (eleUuid.isNull() || backupPoint.m_uuid != eleUuid.text())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QDomElement newNode = doc.createElement(BACKUPPOINT);
|
||||||
|
backupPointToElementNode(backupPoint, doc, newNode);
|
||||||
|
root.replaceChild(newNode, node);
|
||||||
|
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile xmlFile(m_xmlPath);
|
||||||
|
if (!xmlFile.open(QIODevice::WriteOnly)) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream out(&xmlFile);
|
||||||
|
doc.save(out, QDomNode::NodeType::EntityReferenceNode);
|
||||||
|
xmlFile.close();
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,20 @@ public:
|
||||||
*/
|
*/
|
||||||
BackupPoint getLastSysBackupPoint();
|
BackupPoint getLastSysBackupPoint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 新增备份节点
|
||||||
|
* @param backupPoint, 备份点信息
|
||||||
|
* @return SUCCESS成功; XML_PARSE_ERR失败
|
||||||
|
*/
|
||||||
|
ParseResult addItem(const BackupPoint& backupPoint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新备份点信息
|
||||||
|
* @param backupPoint,新的备份点信息
|
||||||
|
* @return SUCCESS成功; XML_PARSE_ERR失败
|
||||||
|
*/
|
||||||
|
ParseResult updateItem(const BackupPoint & backupPoint);
|
||||||
|
|
||||||
inline QString getXmlPath() { return m_xmlPath; }
|
inline QString getXmlPath() { return m_xmlPath; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -75,8 +89,8 @@ private:
|
||||||
bool Doc_setContent(QDomDocument& doc);
|
bool Doc_setContent(QDomDocument& doc);
|
||||||
|
|
||||||
void elementNodeToBackupPoint(const QDomElement& eleNode, BackupPoint& backupPoint);
|
void elementNodeToBackupPoint(const QDomElement& eleNode, BackupPoint& backupPoint);
|
||||||
void backupPointToElementNode(const BackupPoint& backupPoint, QDomElement& eleNode);
|
void backupPointToElementNode(const BackupPoint& backupPoint, QDomDocument& doc, QDomNode& eleNode);
|
||||||
QDomElement createTextElement(const QString& tagName, const QString& text);
|
QDomElement createTextElement(QDomDocument& doc, const QString& tagName, const QString& text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_xmlPath;
|
QString m_xmlPath;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "systembackupproxy.h"
|
#include "systembackupproxy.h"
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <kysec/status.h>
|
||||||
#include "../common/utils.h"
|
#include "../common/utils.h"
|
||||||
#include "../common/mydusizetool.h"
|
#include "../common/mydusizetool.h"
|
||||||
#include "mymountproxy.h"
|
#include "mymountproxy.h"
|
||||||
#include "parsebackuplist.h"
|
|
||||||
#include "myprocess/calcbackupsize.h"
|
#include "myprocess/calcbackupsize.h"
|
||||||
|
|
||||||
IMPLEMENT_DYNCREATE(SystemBackupProxy)
|
IMPLEMENT_DYNCREATE(SystemBackupProxy)
|
||||||
|
@ -13,11 +14,13 @@ SystemBackupProxy::SystemBackupProxy()
|
||||||
{
|
{
|
||||||
m_bSuccess = false;
|
m_bSuccess = false;
|
||||||
m_p = nullptr;
|
m_p = nullptr;
|
||||||
|
m_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemBackupProxy::~SystemBackupProxy()
|
SystemBackupProxy::~SystemBackupProxy()
|
||||||
{
|
{
|
||||||
delete m_p;
|
delete m_p;
|
||||||
|
m_p = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,6 +102,7 @@ bool SystemBackupProxy::checkFreeCapacity()
|
||||||
|
|
||||||
// 1、计算待备份数据的大小
|
// 1、计算待备份数据的大小
|
||||||
qint64 itotalSize = calcSizeForBackup();
|
qint64 itotalSize = calcSizeForBackup();
|
||||||
|
m_size = itotalSize;
|
||||||
// 备份过程中会有一些临时文件产生,会占用一部分空间,故我们预留500M的空间
|
// 备份过程中会有一些临时文件产生,会占用一部分空间,故我们预留500M的空间
|
||||||
itotalSize += 500 * MB;
|
itotalSize += 500 * MB;
|
||||||
|
|
||||||
|
@ -243,6 +247,7 @@ void SystemBackupProxy::doBackup()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动系统备份
|
// 启动系统备份
|
||||||
|
backupSystem();
|
||||||
|
|
||||||
qDebug() << "SystemBackupProxy::doBackup invoke end";
|
qDebug() << "SystemBackupProxy::doBackup invoke end";
|
||||||
}
|
}
|
||||||
|
@ -255,12 +260,12 @@ bool SystemBackupProxy::doPrepare()
|
||||||
{
|
{
|
||||||
qDebug() << "SystemBackupProxy::doPrepare invoke begin";
|
qDebug() << "SystemBackupProxy::doPrepare invoke begin";
|
||||||
|
|
||||||
|
m_bSuccess = false;
|
||||||
|
|
||||||
// 1、设置当前备份的Uuid
|
// 1、设置当前备份的Uuid
|
||||||
if (m_backupWrapper.m_uuid.isEmpty()) {
|
if (m_backupWrapper.m_uuid.isEmpty()) {
|
||||||
// 新增备份点,不指定uuid的场景
|
// 新增备份点,不指定uuid的场景
|
||||||
m_curUuid = "{";
|
|
||||||
m_curUuid += Utils::createUuid();
|
m_curUuid += Utils::createUuid();
|
||||||
m_curUuid += "}";
|
|
||||||
} else {
|
} else {
|
||||||
// 指定uuid备份的场景
|
// 指定uuid备份的场景
|
||||||
m_curUuid = m_backupWrapper.m_uuid;
|
m_curUuid = m_backupWrapper.m_uuid;
|
||||||
|
@ -277,7 +282,7 @@ bool SystemBackupProxy::doPrepare()
|
||||||
|
|
||||||
QString userFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + PATHS_USER_FILE;
|
QString userFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + PATHS_USER_FILE;
|
||||||
userFile.replace("//", "/");
|
userFile.replace("//", "/");
|
||||||
if (Utils::writeFileByLines(userFile, m_backupWrapper.m_backupPaths)) {
|
if (!Utils::writeFileByLines(userFile, m_backupWrapper.m_backupPaths)) {
|
||||||
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
qCritical() << QString("create file %1 failed !").arg(userFile) ;
|
qCritical() << QString("create file %1 failed !").arg(userFile) ;
|
||||||
return false;
|
return false;
|
||||||
|
@ -285,16 +290,53 @@ bool SystemBackupProxy::doPrepare()
|
||||||
|
|
||||||
QString excludeUserFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
|
QString excludeUserFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
|
||||||
excludeUserFile.replace("//", "/");
|
excludeUserFile.replace("//", "/");
|
||||||
if (Utils::writeFileByLines(userFile, m_backupWrapper.m_backupPaths)) {
|
if (!Utils::writeFileByLines(excludeUserFile, m_backupWrapper.m_backupExcludePaths)) {
|
||||||
emit checkResult(int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED));
|
emit checkResult(int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED));
|
||||||
qCritical() << QString("create file %1 failed !").arg(excludeUserFile) ;
|
qCritical() << QString("create file %1 failed !").arg(excludeUserFile) ;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3、记录/backup/snapshots/backuplist.xml文件
|
||||||
|
if (!recordBackupPoint()) {
|
||||||
|
qCritical() << "add or update item to backuplist.xml failed !";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "SystemBackupProxy::doPrepare invoke end";
|
qDebug() << "SystemBackupProxy::doPrepare invoke end";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录/backup/snapshots/backuplist.xml文件
|
||||||
|
* @return true-成功;false-失败
|
||||||
|
*/
|
||||||
|
bool SystemBackupProxy::recordBackupPoint()
|
||||||
|
{
|
||||||
|
m_backupPoint.m_backupName = m_backupWrapper.m_backupName;
|
||||||
|
m_backupPoint.m_uuid = m_curUuid;
|
||||||
|
m_backupPoint.m_iPosition = m_backupWrapper.m_iPosition;
|
||||||
|
m_backupPoint.m_type = m_backupWrapper.m_type;
|
||||||
|
m_backupPoint.m_size = Utils::StringBySize(m_size);
|
||||||
|
m_backupPoint.m_time = QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss");
|
||||||
|
m_backupPoint.m_state = BACKUP_PARSE_STATE_FAIL_STRTING;
|
||||||
|
QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH;
|
||||||
|
xmlPath.replace("//", "/");
|
||||||
|
ParseBackupList parse(xmlPath);
|
||||||
|
if (m_backupWrapper.m_uuid.isEmpty() || !m_backupWrapper.m_bIncrement) {
|
||||||
|
if (parse.addItem(m_backupPoint) != ParseBackupList::SUCCESS) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_ADD_ITEM_FAIL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (parse.updateItem(m_backupPoint) != ParseBackupList::SUCCESS) {
|
||||||
|
emit checkResult(int(BackupResult::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 备份/boot/efi
|
* @brief 备份/boot/efi
|
||||||
* @return true,备份成功;false,备份失败
|
* @return true,备份成功;false,备份失败
|
||||||
|
@ -324,3 +366,71 @@ bool SystemBackupProxy::backupEfi()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 备份系统
|
||||||
|
* @return true,备份成功;false,备份失败
|
||||||
|
*/
|
||||||
|
bool SystemBackupProxy::backupSystem()
|
||||||
|
{
|
||||||
|
qDebug() << "SystemBackupProxy::backupSystem invoke begin";
|
||||||
|
|
||||||
|
QStringList args;
|
||||||
|
if (m_backupWrapper.m_bIncrement) {
|
||||||
|
if (m_backupWrapper.m_uuid.isEmpty()) {
|
||||||
|
// 新增增量备份点场景
|
||||||
|
args = getRsyncArgs(SystemBackupScene::INC_SYSTEM_BACKUP);
|
||||||
|
} else {
|
||||||
|
// 在原来的备份点上增量备份场景
|
||||||
|
args = getRsyncArgs(SystemBackupScene::INC_SYSTEM_BACKUP_AT_BASE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 全量备份场景
|
||||||
|
args = getRsyncArgs(SystemBackupScene::SYSTEM_BACKUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接备份源路径和目标路径
|
||||||
|
QString srcPath = Utils::getSysRootPath();
|
||||||
|
srcPath += "/";
|
||||||
|
srcPath.replace("//", "/");
|
||||||
|
args << srcPath;
|
||||||
|
QString destPath = m_destPath + "/";
|
||||||
|
destPath.replace("//", "/");
|
||||||
|
args << destPath;
|
||||||
|
|
||||||
|
m_p = new RsyncPathToDirProcess(this);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::progress, this, &SystemBackupProxy::progress);
|
||||||
|
connect(m_p, &RsyncPathToDirProcess::finished, this, [&](bool result) {
|
||||||
|
if (result) {
|
||||||
|
m_backupPoint.m_state = BACKUP_PARSE_STATE_SUCCESS_STRTING;
|
||||||
|
QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH;
|
||||||
|
xmlPath.replace("//", "/");
|
||||||
|
ParseBackupList parse(xmlPath);
|
||||||
|
parse.updateItem(m_backupPoint);
|
||||||
|
|
||||||
|
Utils::writeBackupLog(m_backupPoint.m_time + ","
|
||||||
|
+ m_curUuid + "," + QString::number(m_backupWrapper.m_type) + ","
|
||||||
|
+ m_backupWrapper.m_note + "," + m_backupPoint.m_size);
|
||||||
|
m_bSuccess = true;
|
||||||
|
}
|
||||||
|
emit this->workResult(result);
|
||||||
|
});
|
||||||
|
m_p->start(args, false);
|
||||||
|
|
||||||
|
do_kylin_security(m_destPath);
|
||||||
|
|
||||||
|
qDebug() << "SystemBackupProxy::backupSystem invoke end";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemBackupProxy::do_kylin_security(const QString& dstDir)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = kysec_getstatus();
|
||||||
|
if (ret > 0) {
|
||||||
|
QString seFilePath(dstDir + "/.exectl");
|
||||||
|
QFile file(seFilePath);
|
||||||
|
file.open(QIODevice::WriteOnly);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "workerfactory.h"
|
#include "workerfactory.h"
|
||||||
#include "myprocess/rsyncpathtodirprocess.h"
|
#include "myprocess/rsyncpathtodirprocess.h"
|
||||||
|
#include "parsebackuplist.h"
|
||||||
|
|
||||||
class SystemBackupProxy : public Worker
|
class SystemBackupProxy : public Worker
|
||||||
{
|
{
|
||||||
|
@ -50,6 +51,12 @@ private:
|
||||||
*/
|
*/
|
||||||
QStringList getRsyncArgs(SystemBackupScene scene);
|
QStringList getRsyncArgs(SystemBackupScene scene);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录/backup/snapshots/backuplist.xml文件
|
||||||
|
* @return true-成功;false-失败
|
||||||
|
*/
|
||||||
|
bool recordBackupPoint();
|
||||||
|
|
||||||
// 备份准备
|
// 备份准备
|
||||||
bool doPrepare();
|
bool doPrepare();
|
||||||
|
|
||||||
|
@ -59,14 +66,23 @@ private:
|
||||||
// 备份/boot/efi
|
// 备份/boot/efi
|
||||||
bool backupEfi();
|
bool backupEfi();
|
||||||
|
|
||||||
|
// 备份系统
|
||||||
|
bool backupSystem();
|
||||||
|
|
||||||
|
void do_kylin_security(const QString& dstDir);
|
||||||
|
|
||||||
// 是否备份成功
|
// 是否备份成功
|
||||||
bool m_bSuccess;
|
bool m_bSuccess;
|
||||||
// 当前备份uuid
|
// 当前备份uuid
|
||||||
QString m_curUuid;
|
QString m_curUuid;
|
||||||
// 当前备份目标目录
|
// 当前备份目标目录
|
||||||
QString m_destPath;
|
QString m_destPath;
|
||||||
|
// 当前备份所需空间大小
|
||||||
|
qint64 m_size;
|
||||||
// 备份进程
|
// 备份进程
|
||||||
RsyncPathToDirProcess *m_p;
|
RsyncPathToDirProcess *m_p;
|
||||||
|
// 当前备份节点
|
||||||
|
ParseBackupList::BackupPoint m_backupPoint;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,9 @@ void Worker::cancel()
|
||||||
|
|
||||||
// 环境检测,个性化部分派生类去实现
|
// 环境检测,个性化部分派生类去实现
|
||||||
bool Worker::checkEnvEx()
|
bool Worker::checkEnvEx()
|
||||||
{}
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 任务处理,个性化部分派生类去实现
|
// 任务处理,个性化部分派生类去实现
|
||||||
void Worker::doWorkEx()
|
void Worker::doWorkEx()
|
||||||
|
|
|
@ -18,6 +18,8 @@ public:
|
||||||
signals:
|
signals:
|
||||||
// 检测结果信号
|
// 检测结果信号
|
||||||
void checkResult(int result);
|
void checkResult(int result);
|
||||||
|
// 进度百分比
|
||||||
|
void progress(int currentRate);
|
||||||
// 工作结果信号
|
// 工作结果信号
|
||||||
void workResult(bool result);
|
void workResult(bool result);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define BACKUP_XML_PATH "/backup/snapshots/backuplist.xml"
|
#define BACKUP_XML_PATH "/backup/snapshots/backuplist.xml"
|
||||||
#define EXCLUDE_FILE_PATH "/backup/snapshots/.exclude"
|
#define EXCLUDE_FILE_PATH "/backup/snapshots/.exclude"
|
||||||
#define CHECK_PATH "/backup/snapshots/check/data/"
|
#define CHECK_PATH "/backup/snapshots/check/data/"
|
||||||
|
#define BACKUP_LOG_TEXT_PATH "/backup/log.txt"
|
||||||
|
|
||||||
#define BOOTINFO_PATH "/etc/.bootinfo"
|
#define BOOTINFO_PATH "/etc/.bootinfo"
|
||||||
#define FSTAB_PATH "/etc/fstab"
|
#define FSTAB_PATH "/etc/fstab"
|
||||||
|
@ -28,6 +29,11 @@
|
||||||
#define PATHS_USER_FILE ".user.txt"
|
#define PATHS_USER_FILE ".user.txt"
|
||||||
#define EXCLUDE_PATHS_USER_FILE ".exclude.user.txt"
|
#define EXCLUDE_PATHS_USER_FILE ".exclude.user.txt"
|
||||||
|
|
||||||
|
#define BACKUP_PARSE_STATE_SUCCESS_STRTING "backup finished"
|
||||||
|
#define BACKUP_PARSE_STATE_FAIL_STRTING "backup unfinished"
|
||||||
|
#define BACKUP_PARSE_STATE_INC_SUCCESS_STRTING "inc backup finished"
|
||||||
|
#define BACKUP_PARSE_STATE_INC_FAIL_STRTING "inc backup unfinished"
|
||||||
|
|
||||||
#define PID_STRING_LEN 1024
|
#define PID_STRING_LEN 1024
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
#include "mylittleparse.h"
|
#include "mylittleparse.h"
|
||||||
#include "mydefine.h"
|
#include "mydefine.h"
|
||||||
|
|
||||||
|
@ -423,6 +428,85 @@ bool Utils::writeFileByLines(const QString& fileName, const QStringList& lines)
|
||||||
for (const QString& line : lines) {
|
for (const QString& line : lines) {
|
||||||
out << line << endl;
|
out << line << endl;
|
||||||
}
|
}
|
||||||
|
out.flush();
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 判断文件是否存在
|
||||||
|
* @param fileName 文件明
|
||||||
|
* @return bool,true-存在;false-不存在
|
||||||
|
* @author zhaominyong
|
||||||
|
* @since 2021/05/29
|
||||||
|
*/
|
||||||
|
bool Utils::filsExists(const QString &fileName)
|
||||||
|
{
|
||||||
|
struct stat buffer;
|
||||||
|
return (stat(fileName.toStdString().data(), &buffer) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录备份日志
|
||||||
|
* @param line,日志内容
|
||||||
|
* @return bool, true-成功;false-失败
|
||||||
|
* @author zhaominyong
|
||||||
|
* @since 2021/05/29
|
||||||
|
* @note
|
||||||
|
* 因为系统恢复成功后马上需要reboot,但是此时的文件缓存可能还未能落盘,故此增加此函数,其中调用了系统函数fdatasync确保缓存落盘
|
||||||
|
*/
|
||||||
|
bool Utils::writeBackupLog(QString line)
|
||||||
|
{
|
||||||
|
line = line + "\n";
|
||||||
|
QString logFile = Utils::getSysRootPath() + BACKUP_LOG_TEXT_PATH;
|
||||||
|
logFile.replace("//", "/");
|
||||||
|
std::string fileName(logFile.toStdString());
|
||||||
|
// 判断文件是否存在
|
||||||
|
bool exists = filsExists(logFile);
|
||||||
|
|
||||||
|
std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(std::fopen(fileName.data(), "a+"), std::fclose);
|
||||||
|
|
||||||
|
if (!fp) {
|
||||||
|
std::perror("file opening failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
std::fputs("#This file must not be deleted and it is for the backup tool.\n", fp.get());
|
||||||
|
std::fputs("#0:new system backup\n", fp.get());
|
||||||
|
std::fputs("#1:update system backup\n", fp.get());
|
||||||
|
std::fputs("#2:new data backup\n", fp.get());
|
||||||
|
std::fputs("#3:update data backup\n", fp.get());
|
||||||
|
std::fputs("#4:restore system\n", fp.get());
|
||||||
|
std::fputs("#5:retaining user data\n", fp.get());
|
||||||
|
std::fputs("#6:restore data\n", fp.get());
|
||||||
|
std::fputs("#8:delete backup\n", fp.get());
|
||||||
|
std::fputs("#for example: 17-04-25 10:43:56,{uuidxxxxx},0,this is a note\n", fp.get());
|
||||||
|
}
|
||||||
|
std::fputs(line.toStdString().data(), fp.get());
|
||||||
|
std::fflush(fp.get());
|
||||||
|
fdatasync(fileno(fp.get()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将字节大小转换为GB等表示的字符串
|
||||||
|
* @param size,qint64,空间大小,单位字节
|
||||||
|
* @return GB/MB/KB等表示的字符串型大小
|
||||||
|
*/
|
||||||
|
QString Utils::StringBySize(qint64 size)
|
||||||
|
{
|
||||||
|
#define GB (1024 * 1024 * 1024)
|
||||||
|
#define MB (1024 * 1024)
|
||||||
|
#define KB (1024)
|
||||||
|
|
||||||
|
float fcount = size * 1.0;
|
||||||
|
|
||||||
|
if (size > GB)
|
||||||
|
return QString(QString::number(fcount / GB, 10, 2) + "GB");
|
||||||
|
else if (size > MB)
|
||||||
|
return QString(QString::number(fcount / MB, 10, 2) + "MB");
|
||||||
|
else
|
||||||
|
return QString(QString::number(fcount / KB, 10, 2) + "KB");
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,33 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool writeFileByLines(const QString& fileName, const QStringList& lines);
|
static bool writeFileByLines(const QString& fileName, const QStringList& lines);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 判断文件是否存在
|
||||||
|
* @param fileName 文件明
|
||||||
|
* @return bool,true-存在;false-不存在
|
||||||
|
* @author zhaominyong
|
||||||
|
* @since 2021/05/29
|
||||||
|
*/
|
||||||
|
static bool filsExists(const QString &fileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 记录备份日志
|
||||||
|
* @param line,日志内容
|
||||||
|
* @return bool, true-成功;false-失败
|
||||||
|
* @author zhaominyong
|
||||||
|
* @since 2021/05/29
|
||||||
|
* @note
|
||||||
|
* 因为系统恢复成功后马上需要reboot,但是此时的文件缓存可能还未能落盘,故此增加此函数,其中调用了系统函数fdatasync确保缓存落盘
|
||||||
|
*/
|
||||||
|
static bool writeBackupLog(QString line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将字节大小转换为GB等表示的字符串
|
||||||
|
* @param size,qint64,空间大小,单位字节
|
||||||
|
* @return GB/MB/KB等表示的字符串型大小
|
||||||
|
*/
|
||||||
|
static QString StringBySize(qint64 size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 系统根目录,默认"/"
|
// 系统根目录,默认"/"
|
||||||
static QString m_sysRootPath;
|
static QString m_sysRootPath;
|
||||||
|
|
|
@ -121,6 +121,8 @@ public Q_SLOTS: // METHODS
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_SIGNALS: // SIGNALS
|
Q_SIGNALS: // SIGNALS
|
||||||
|
void backupFinished(bool result);
|
||||||
|
void progress(int in0, int in1);
|
||||||
void sendBackupResult(bool result);
|
void sendBackupResult(bool result);
|
||||||
void sendDeleteResult(bool result);
|
void sendDeleteResult(bool result);
|
||||||
void sendEnvCheckResult(int result);
|
void sendEnvCheckResult(int result);
|
||||||
|
|
Loading…
Reference in New Issue