backup-daemon:本地系统备份逻辑基本完成
This commit is contained in:
parent
46d4c5c38a
commit
dba7168325
|
@ -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
|
||||
|
|
|
@ -55,6 +55,13 @@ class ManagerAdaptor: public QDBusAbstractAdaptor
|
|||
" <signal name=\"sendGhostBackupResult\">\n"
|
||||
" <arg direction=\"out\" type=\"b\" name=\"result\"/>\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"
|
||||
" <arg direction=\"out\" type=\"i\"/>\n"
|
||||
" </method>\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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
// 删除备份结果信号
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,6 +29,7 @@ RsyncPathToDirProcess::RsyncPathToDirProcess(QObject *parent) :
|
|||
});
|
||||
|
||||
connect(m_p, &QProcess::errorOccurred, this, [&](QProcess::ProcessError error) {
|
||||
Q_UNUSED(error)
|
||||
m_p->kill();
|
||||
});
|
||||
|
||||
|
|
|
@ -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 <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;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "systembackupproxy.h"
|
||||
#include <QStorageInfo>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <kysec/status.h>
|
||||
#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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ void Worker::cancel()
|
|||
|
||||
// 环境检测,个性化部分派生类去实现
|
||||
bool Worker::checkEnvEx()
|
||||
{}
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 任务处理,个性化部分派生类去实现
|
||||
void Worker::doWorkEx()
|
||||
|
|
|
@ -18,6 +18,8 @@ public:
|
|||
signals:
|
||||
// 检测结果信号
|
||||
void checkResult(int result);
|
||||
// 进度百分比
|
||||
void progress(int currentRate);
|
||||
// 工作结果信号
|
||||
void workResult(bool result);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#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<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);
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue