diff --git a/backup-daemon/backup-daemon.pro b/backup-daemon/backup-daemon.pro
index fd9bcc5..9c18348 100755
--- a/backup-daemon/backup-daemon.pro
+++ b/backup-daemon/backup-daemon.pro
@@ -7,6 +7,9 @@ CONFIG -= app_bundle
CONFIG += link_pkgconfig
+LIBS += -lblkid \
+ -lkysec
+
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
diff --git a/backup-daemon/backupmanager_adaptor.h b/backup-daemon/backupmanager_adaptor.h
index ad82080..d283c28 100755
--- a/backup-daemon/backupmanager_adaptor.h
+++ b/backup-daemon/backupmanager_adaptor.h
@@ -55,6 +55,13 @@ class ManagerAdaptor: public QDBusAbstractAdaptor
" \n"
" \n"
" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
" \n"
" \n"
" \n"
@@ -122,6 +129,8 @@ public Q_SLOTS: // METHODS
int goRestore(BackupWrapper backupWrapper);
int cancel(BackupWrapper backupWrapper);
Q_SIGNALS: // SIGNALS
+ void backupFinished(bool result);
+ void progress(int in0, int in1);
void sendBackupResult(bool result);
void sendDeleteResult(bool result);
void sendEnvCheckResult(int result);
diff --git a/backup-daemon/main.cpp b/backup-daemon/main.cpp
index a482667..bbd0516 100755
--- a/backup-daemon/main.cpp
+++ b/backup-daemon/main.cpp
@@ -30,9 +30,10 @@ int main(int argc, char *argv[])
qDebug() << QString("测试 begin");
BackupWrapper backupWrapper;
+ backupWrapper.m_backupName = "赵民勇test";
backupWrapper.m_backupExcludePaths = Utils::getFromExcludePathsFile();
MyBackupManager manager;
- manager.checkEnv(backupWrapper);
+ manager.goBackup(backupWrapper);
qDebug() << QString("测试 end");
// test end
diff --git a/backup-daemon/mybackupmanager.cpp b/backup-daemon/mybackupmanager.cpp
index 0f86d20..385cc1a 100755
--- a/backup-daemon/mybackupmanager.cpp
+++ b/backup-daemon/mybackupmanager.cpp
@@ -95,6 +95,9 @@ int MyBackupManager::goBackup(const BackupWrapper& backupWrapper)
this->finished();
}
});
+ connect(worker, &Worker::progress, this, [&](int rate) {
+ emit this->progress(int(BackupState::WORKING), rate);
+ });
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->sendBackupResult(result);
this->finished();
@@ -187,6 +190,7 @@ int MyBackupManager::getBackupState(bool& isActive)
*/
int MyBackupManager::cancel(const BackupWrapper& backupWrapper)
{
+ Q_UNUSED(backupWrapper)
return 0;
}
diff --git a/backup-daemon/mybackupmanager.h b/backup-daemon/mybackupmanager.h
index c65b4f0..478e7a7 100755
--- a/backup-daemon/mybackupmanager.h
+++ b/backup-daemon/mybackupmanager.h
@@ -17,14 +17,21 @@ public:
virtual ~MyBackupManager();
signals:
- // 环境检查结果信号
- void sendEnvCheckResult(int result);
+ // 这3个信号供控制面板/自动更新等外围模块使用
// 开始备份结果信号
void sendStartBackupResult(int result);
// 备份结果信号
void sendBackupResult(bool result);
// 进度信号
void sendRate(int, int);
+
+ // 模块内使用的信号
+ // 进度信号
+ void progress(int, int);
+ // 备份结果信号
+ void backupFinished(bool result);
+ // 环境检查结果信号
+ void sendEnvCheckResult(int result);
// 还原结果信号
void sendRestoreResult(bool result);
// 删除备份结果信号
diff --git a/backup-daemon/myprocess/calcbackupsize.cpp b/backup-daemon/myprocess/calcbackupsize.cpp
index 45a965b..032d66a 100755
--- a/backup-daemon/myprocess/calcbackupsize.cpp
+++ b/backup-daemon/myprocess/calcbackupsize.cpp
@@ -15,6 +15,7 @@ CalcBackupSize::CalcBackupSize(QObject* parent) :
});
connect(m_process, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
+ Q_UNUSED(error)
m_process->kill();
});
@@ -89,7 +90,6 @@ void CalcBackupSize::parseResult()
QString out(m_process->readAll());
QStringList lines = out.split("\n");
for (QString& line : lines) {
- line.trimmed();
// 获取文件夹数目
// if (line.startsWith("Number of files:")) {
// int indexOfDir = line.indexOf("dir: ");
@@ -102,7 +102,7 @@ void CalcBackupSize::parseResult()
// m_size += numOfDirs * 4096;
// }
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)
{
qDebug() << "CalcBackupSize::getCalcResult invoke begin";
+ Q_UNUSED(exitCode)
parseResult();
emit finished(m_size);
diff --git a/backup-daemon/myprocess/rsyncpathtodirprocess.cpp b/backup-daemon/myprocess/rsyncpathtodirprocess.cpp
index c11baa3..3f157b5 100755
--- a/backup-daemon/myprocess/rsyncpathtodirprocess.cpp
+++ b/backup-daemon/myprocess/rsyncpathtodirprocess.cpp
@@ -29,6 +29,7 @@ RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
});
connect(m_p, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
+ Q_UNUSED(error)
m_p->kill();
});
diff --git a/backup-daemon/parsebackuplist.cpp b/backup-daemon/parsebackuplist.cpp
index 282e007..e21f4fd 100755
--- a/backup-daemon/parsebackuplist.cpp
+++ b/backup-daemon/parsebackuplist.cpp
@@ -301,15 +301,15 @@ void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPo
* @param backupPoint, BackupPoint
* @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(TIME, backupPoint.m_time));
- node.appendChild(createTextElement(UUID, backupPoint.m_uuid));
- node.appendChild(createTextElement(SIZE, backupPoint.m_size));
- node.appendChild(createTextElement(STATE, backupPoint.m_state));
- node.appendChild(createTextElement(TYPE, QString::number(backupPoint.m_type)));
- node.appendChild(createTextElement(POSITION, QString::number(backupPoint.m_iPosition)));
+ node.appendChild(createTextElement(doc, COMMENT, backupPoint.m_backupName));
+ node.appendChild(createTextElement(doc, TIME, backupPoint.m_time));
+ node.appendChild(createTextElement(doc, UUID, backupPoint.m_uuid));
+ node.appendChild(createTextElement(doc, SIZE, backupPoint.m_size));
+ node.appendChild(createTextElement(doc, STATE, backupPoint.m_state));
+ node.appendChild(createTextElement(doc, TYPE, QString::number(backupPoint.m_type)));
+ node.appendChild(createTextElement(doc, POSITION, QString::number(backupPoint.m_iPosition)));
}
/**
@@ -318,13 +318,79 @@ void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, Q
* @param text
* @return text
*/
-QDomElement ParseBackupList::createTextElement(const QString& tagName, const QString& text)
+QDomElement ParseBackupList::createTextElement(QDomDocument& doc, const QString& tagName, const QString& text)
{
- QDomElement node;
- node.setTagName(tagName);
- QDomText textNode;
- textNode.setData(text);
+ QDomElement node = doc.createElement(tagName);
+ QDomText textNode = doc.createTextNode(text);
node.appendChild(textNode);
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;
+}
diff --git a/backup-daemon/parsebackuplist.h b/backup-daemon/parsebackuplist.h
index 24350aa..53a77be 100755
--- a/backup-daemon/parsebackuplist.h
+++ b/backup-daemon/parsebackuplist.h
@@ -67,6 +67,20 @@ public:
*/
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; }
private:
@@ -75,8 +89,8 @@ private:
bool Doc_setContent(QDomDocument& doc);
void elementNodeToBackupPoint(const QDomElement& eleNode, BackupPoint& backupPoint);
- void backupPointToElementNode(const BackupPoint& backupPoint, QDomElement& eleNode);
- QDomElement createTextElement(const QString& tagName, const QString& text);
+ void backupPointToElementNode(const BackupPoint& backupPoint, QDomDocument& doc, QDomNode& eleNode);
+ QDomElement createTextElement(QDomDocument& doc, const QString& tagName, const QString& text);
private:
QString m_xmlPath;
diff --git a/backup-daemon/systembackupproxy.cpp b/backup-daemon/systembackupproxy.cpp
index 561d6a8..43d5fc6 100755
--- a/backup-daemon/systembackupproxy.cpp
+++ b/backup-daemon/systembackupproxy.cpp
@@ -1,10 +1,11 @@
#include "systembackupproxy.h"
#include
+#include
#include
+#include
#include "../common/utils.h"
#include "../common/mydusizetool.h"
#include "mymountproxy.h"
-#include "parsebackuplist.h"
#include "myprocess/calcbackupsize.h"
IMPLEMENT_DYNCREATE(SystemBackupProxy)
@@ -13,11 +14,13 @@ SystemBackupProxy::SystemBackupProxy()
{
m_bSuccess = false;
m_p = nullptr;
+ m_size = 0;
}
SystemBackupProxy::~SystemBackupProxy()
{
delete m_p;
+ m_p = nullptr;
}
/**
@@ -99,6 +102,7 @@ bool SystemBackupProxy::checkFreeCapacity()
// 1、计算待备份数据的大小
qint64 itotalSize = calcSizeForBackup();
+ m_size = itotalSize;
// 备份过程中会有一些临时文件产生,会占用一部分空间,故我们预留500M的空间
itotalSize += 500 * MB;
@@ -243,6 +247,7 @@ void SystemBackupProxy::doBackup()
}
// 启动系统备份
+ backupSystem();
qDebug() << "SystemBackupProxy::doBackup invoke end";
}
@@ -255,12 +260,12 @@ bool SystemBackupProxy::doPrepare()
{
qDebug() << "SystemBackupProxy::doPrepare invoke begin";
+ m_bSuccess = false;
+
// 1、设置当前备份的Uuid
if (m_backupWrapper.m_uuid.isEmpty()) {
// 新增备份点,不指定uuid的场景
- m_curUuid = "{";
m_curUuid += Utils::createUuid();
- m_curUuid += "}";
} else {
// 指定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;
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));
qCritical() << QString("create file %1 failed !").arg(userFile) ;
return false;
@@ -285,16 +290,53 @@ bool SystemBackupProxy::doPrepare()
QString excludeUserFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE;
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));
qCritical() << QString("create file %1 failed !").arg(excludeUserFile) ;
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";
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
* @return true,备份成功;false,备份失败
@@ -324,3 +366,71 @@ bool SystemBackupProxy::backupEfi()
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();
+ }
+}
+
diff --git a/backup-daemon/systembackupproxy.h b/backup-daemon/systembackupproxy.h
index 480733a..fbb9bdf 100755
--- a/backup-daemon/systembackupproxy.h
+++ b/backup-daemon/systembackupproxy.h
@@ -3,6 +3,7 @@
#include "workerfactory.h"
#include "myprocess/rsyncpathtodirprocess.h"
+#include "parsebackuplist.h"
class SystemBackupProxy : public Worker
{
@@ -50,6 +51,12 @@ private:
*/
QStringList getRsyncArgs(SystemBackupScene scene);
+ /**
+ * @brief 记录/backup/snapshots/backuplist.xml文件
+ * @return true-成功;false-失败
+ */
+ bool recordBackupPoint();
+
// 备份准备
bool doPrepare();
@@ -59,14 +66,23 @@ private:
// 备份/boot/efi
bool backupEfi();
+ // 备份系统
+ bool backupSystem();
+
+ void do_kylin_security(const QString& dstDir);
+
// 是否备份成功
bool m_bSuccess;
// 当前备份uuid
QString m_curUuid;
// 当前备份目标目录
QString m_destPath;
+ // 当前备份所需空间大小
+ qint64 m_size;
// 备份进程
RsyncPathToDirProcess *m_p;
+ // 当前备份节点
+ ParseBackupList::BackupPoint m_backupPoint;
};
diff --git a/backup-daemon/workerfactory.cpp b/backup-daemon/workerfactory.cpp
index 4842ab9..77dea36 100755
--- a/backup-daemon/workerfactory.cpp
+++ b/backup-daemon/workerfactory.cpp
@@ -35,7 +35,9 @@ void Worker::cancel()
// 环境检测,个性化部分派生类去实现
bool Worker::checkEnvEx()
-{}
+{
+ return true;
+}
// 任务处理,个性化部分派生类去实现
void Worker::doWorkEx()
diff --git a/backup-daemon/workerfactory.h b/backup-daemon/workerfactory.h
index 8a1da39..c554a84 100755
--- a/backup-daemon/workerfactory.h
+++ b/backup-daemon/workerfactory.h
@@ -18,6 +18,8 @@ public:
signals:
// 检测结果信号
void checkResult(int result);
+ // 进度百分比
+ void progress(int currentRate);
// 工作结果信号
void workResult(bool result);
diff --git a/common/mydefine.h b/common/mydefine.h
index c3eae96..5b32eef 100755
--- a/common/mydefine.h
+++ b/common/mydefine.h
@@ -13,6 +13,7 @@
#define BACKUP_XML_PATH "/backup/snapshots/backuplist.xml"
#define EXCLUDE_FILE_PATH "/backup/snapshots/.exclude"
#define CHECK_PATH "/backup/snapshots/check/data/"
+#define BACKUP_LOG_TEXT_PATH "/backup/log.txt"
#define BOOTINFO_PATH "/etc/.bootinfo"
#define FSTAB_PATH "/etc/fstab"
@@ -28,6 +29,11 @@
#define PATHS_USER_FILE ".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
/**
diff --git a/common/utils.cpp b/common/utils.cpp
index f05fced..f487c7c 100755
--- a/common/utils.cpp
+++ b/common/utils.cpp
@@ -13,6 +13,11 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+
#include "mylittleparse.h"
#include "mydefine.h"
@@ -423,6 +428,85 @@ bool Utils::writeFileByLines(const QString& fileName, const QStringList& lines)
for (const QString& line : lines) {
out << line << endl;
}
+ out.flush();
file.close();
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 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");
+}
diff --git a/common/utils.h b/common/utils.h
index d32e5f7..2c46a3a 100755
--- a/common/utils.h
+++ b/common/utils.h
@@ -119,6 +119,33 @@ public:
*/
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:
// 系统根目录,默认"/"
static QString m_sysRootPath;
diff --git a/kybackup/backup_manager_interface.h b/kybackup/backup_manager_interface.h
index 2cde03d..7a70d50 100644
--- a/kybackup/backup_manager_interface.h
+++ b/kybackup/backup_manager_interface.h
@@ -121,6 +121,8 @@ public Q_SLOTS: // METHODS
}
Q_SIGNALS: // SIGNALS
+ void backupFinished(bool result);
+ void progress(int in0, int in1);
void sendBackupResult(bool result);
void sendDeleteResult(bool result);
void sendEnvCheckResult(int result);