This commit is contained in:
parent
1d634ef885
commit
272456a31d
|
@ -1,6 +1,6 @@
|
|||
QT += core
|
||||
QT -= gui
|
||||
QT += dbus
|
||||
QT += dbus xml
|
||||
|
||||
CONFIG += c++11 console
|
||||
CONFIG -= app_bundle
|
||||
|
@ -20,6 +20,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||
|
||||
HEADERS += \
|
||||
../common/mydefine.h \
|
||||
../common/mydusizetool.h \
|
||||
../common/mylittleparse.h \
|
||||
../common/reflect.h \
|
||||
../common/singleton.h \
|
||||
|
@ -29,11 +30,13 @@ HEADERS += \
|
|||
mybackupmanager.h \
|
||||
mymountproxy.h \
|
||||
myprocess/mountbackupprocess.h \
|
||||
parsebackuplist.h \
|
||||
systembackupproxy.h \
|
||||
workerfactory.h
|
||||
|
||||
SOURCES += \
|
||||
../common/mydefine.cpp \
|
||||
../common/mydusizetool.cpp \
|
||||
../common/mylittleparse.cpp \
|
||||
../common/reflect.cpp \
|
||||
../common/utils.cpp \
|
||||
|
@ -42,6 +45,7 @@ SOURCES += \
|
|||
mybackupmanager.cpp \
|
||||
mymountproxy.cpp \
|
||||
myprocess/mountbackupprocess.cpp \
|
||||
parsebackuplist.cpp \
|
||||
systembackupproxy.cpp \
|
||||
workerfactory.cpp
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "backupmanager_adaptor.h"
|
||||
|
||||
// test begin
|
||||
#include <QDebug>
|
||||
#include "../common/reflect.h"
|
||||
#include "mymountproxy.h"
|
||||
// test end
|
||||
|
@ -27,9 +28,12 @@ int main(int argc, char *argv[])
|
|||
//MyMountProxy * proxy = (MyMountProxy*)Reflect::createObject("MyMountProxy");
|
||||
//proxy->mountBackupPartition();
|
||||
|
||||
qDebug() << QString("测试 begin");
|
||||
BackupWrapper backupWrapper;
|
||||
MyBackupManager manager;
|
||||
manager.checkEnv(backupWrapper);
|
||||
|
||||
qDebug() << QString("测试 end");
|
||||
// test end
|
||||
|
||||
MyBackupManager* backup_deamon = new MyBackupManager;
|
||||
|
|
|
@ -63,6 +63,8 @@ int MyBackupManager::checkEnv(const BackupWrapper& backupWrapper)
|
|||
connect(&workerThread, &QThread::started, worker, &Worker::checkEnv);
|
||||
connect(&workerThread, &QThread::finished, worker, &Worker::deleteLater);
|
||||
|
||||
workerThread.start();
|
||||
|
||||
return int(BackupResult::BACKUP_RESULT_INIT);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
#include "parsebackuplist.h"
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDebug>
|
||||
|
||||
/*
|
||||
<?xml version='1.0'?>
|
||||
<backupList>
|
||||
<BackupPoint>
|
||||
<Comment>21-07-21 14:14:01</Comment>
|
||||
<Time>21-07-21 14:14:03</Time>
|
||||
<Uuid>{beecb746-561f-4fa1-99ba-19fb849a1ba7}</Uuid>
|
||||
<Size>24.26KB</Size>
|
||||
<State>backup finished</State>
|
||||
<Type>2</Type>
|
||||
</BackupPoint>
|
||||
</backupList>
|
||||
*/
|
||||
|
||||
#define BACKUPLIST "backupList"
|
||||
#define BACKUPPOINT "BackupPoint"
|
||||
#define COMMENT "Comment"
|
||||
#define TIME "Time"
|
||||
#define UUID "Uuid"
|
||||
#define SIZE "Size"
|
||||
#define STATE "State"
|
||||
#define TYPE "Type"
|
||||
#define POSITION "Position"
|
||||
#define STATUE_BACKUP_FINESHED "backup finished"
|
||||
|
||||
ParseBackupList::ParseBackupList(const QString& xmlPath)
|
||||
: m_xmlPath(xmlPath)
|
||||
{
|
||||
QFile xmlFile(m_xmlPath);
|
||||
if (!xmlFile.exists() || 0 == xmlFile.size()) {
|
||||
InitXml();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化xml文件
|
||||
* @return
|
||||
*/
|
||||
bool ParseBackupList::InitXml()
|
||||
{
|
||||
QFile xmlFile(m_xmlPath);
|
||||
if (!xmlFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
|
||||
return false;
|
||||
|
||||
QDomDocument doc;
|
||||
|
||||
QDomProcessingInstruction ins = doc.createProcessingInstruction("xml", "version=\'1.0\'");
|
||||
doc.appendChild(ins);
|
||||
|
||||
QDomElement root = doc.createElement(BACKUPLIST);
|
||||
doc.appendChild(root);
|
||||
|
||||
QTextStream out(&xmlFile);
|
||||
doc.save(out, QDomNode::NodeType::CDATASectionNode);
|
||||
|
||||
xmlFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 校验xml格式是否正确
|
||||
* @return
|
||||
*/
|
||||
bool ParseBackupList::isXmlCorrect()
|
||||
{
|
||||
QFile xmlFile(m_xmlPath);
|
||||
if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qDebug() << "Open file " << m_xmlPath << " failure";
|
||||
return false;
|
||||
}
|
||||
QXmlStreamReader reader(&xmlFile);
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.isStartElement()) {
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
if (reader.hasError()) {
|
||||
qDebug() << "xml parse error!";
|
||||
xmlFile.close();
|
||||
return false;
|
||||
}
|
||||
xmlFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取xml文件
|
||||
* @param doc
|
||||
* @return
|
||||
*/
|
||||
bool ParseBackupList::Doc_setContent(QDomDocument& doc)
|
||||
{
|
||||
QFile xmlFile(m_xmlPath);
|
||||
if (!xmlFile.open(QIODevice::ReadOnly)) {
|
||||
qDebug() << " open backuplist.xml failed!";
|
||||
return false;
|
||||
}
|
||||
QString errStr;
|
||||
int errLine;
|
||||
int errCol;
|
||||
|
||||
if (!doc.setContent(&xmlFile, false, &errStr, &errLine, &errCol)) {
|
||||
qDebug() << QString("parse backuplist.xml error at line %1, column %2:%3").arg(errLine).arg(errCol).arg(errStr);
|
||||
xmlFile.close();
|
||||
return false;
|
||||
}
|
||||
xmlFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 出厂备份修改backuplist.xml,仅保留出厂备份信息
|
||||
* @param factoryBackupUuid,出厂备份的uuid
|
||||
* @return ParseResult枚举类型
|
||||
* @author zhaominyong
|
||||
* @since 2021/06/27
|
||||
*/
|
||||
ParseBackupList::ParseResult ParseBackupList::updateForFactoryRestore(const QString& factoryBackupUuid)
|
||||
{
|
||||
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 element = node.toElement();
|
||||
QDomNodeList nodes = element.elementsByTagName(UUID);
|
||||
if (0 < nodes.count()) {
|
||||
QDomElement uuidElement = nodes.at(0).toElement();
|
||||
QString tag = uuidElement.tagName();
|
||||
QString text = uuidElement.text();
|
||||
if (uuidElement.text() != factoryBackupUuid) {
|
||||
root.removeChild(node);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QFile xmlFile(m_xmlPath);
|
||||
if (!xmlFile.open(QIODevice::WriteOnly)) {
|
||||
qDebug() << "update state failed";
|
||||
return FAIL;
|
||||
}
|
||||
QTextStream out(&xmlFile);
|
||||
doc.save(out, QDomNode::NodeType::EntityReferenceNode);
|
||||
out.flush();
|
||||
xmlFile.close();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据comment查找uuid
|
||||
* @param comment
|
||||
* @return uuid
|
||||
*/
|
||||
QString ParseBackupList::findUuidByComment(const QString& comment)
|
||||
{
|
||||
QDomDocument doc;
|
||||
if (!Doc_setContent(doc))
|
||||
return "";
|
||||
|
||||
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 eleComment = node.firstChildElement(COMMENT);
|
||||
if (eleComment.isNull())
|
||||
continue;
|
||||
|
||||
if (comment != eleComment.text())
|
||||
continue;
|
||||
|
||||
QDomElement eleUuid = node.firstChildElement(UUID);
|
||||
if (eleUuid.isNull())
|
||||
return "";
|
||||
|
||||
return eleUuid.text();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据Uuid查找备份点信息
|
||||
* @param Uuid
|
||||
* @return 备份点信息
|
||||
*/
|
||||
ParseBackupList::BackupPoint ParseBackupList::findBackupPointByUuid(const QString& Uuid)
|
||||
{
|
||||
BackupPoint backupPoint;
|
||||
QDomDocument doc;
|
||||
if (!Doc_setContent(doc))
|
||||
return backupPoint;
|
||||
|
||||
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() || Uuid != eleUuid.text())
|
||||
continue;
|
||||
|
||||
elementNodeToBackupPoint(node.toElement(), backupPoint);
|
||||
return backupPoint;
|
||||
}
|
||||
|
||||
return backupPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取最后一次系统备份
|
||||
* @return
|
||||
*/
|
||||
ParseBackupList::BackupPoint ParseBackupList::getLastSysBackupPoint()
|
||||
{
|
||||
BackupPoint backupPoint;
|
||||
QDomDocument doc;
|
||||
if (!Doc_setContent(doc))
|
||||
return backupPoint;
|
||||
|
||||
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 eleType = node.firstChildElement(TYPE);
|
||||
if (eleType.isNull() || (BackupType::BACKUP_SYSTEM != eleType.text().toInt() && BackupType::INC_BACKUP_SYSTEM != eleType.text().toInt()))
|
||||
continue;
|
||||
|
||||
QDomElement eleState = node.firstChildElement(STATE);
|
||||
QString type = eleState.text();
|
||||
if (eleState.isNull() || eleState.text() != QString(STATUE_BACKUP_FINESHED))
|
||||
continue;
|
||||
|
||||
elementNodeToBackupPoint(node.toElement(), backupPoint);
|
||||
}
|
||||
|
||||
return backupPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief elementNode --> BackupPoint
|
||||
* @param node, QDomElement
|
||||
* @param backupPoint, BackupPoint
|
||||
*/
|
||||
void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPoint& backupPoint)
|
||||
{
|
||||
QDomElement eleUuid = node.firstChildElement(UUID);
|
||||
if (!eleUuid.isNull())
|
||||
backupPoint.m_uuid = eleUuid.text();
|
||||
|
||||
QDomElement eleComment = node.firstChildElement(COMMENT);
|
||||
if (!eleComment.isNull())
|
||||
backupPoint.m_backupName = eleComment.text();
|
||||
|
||||
QDomElement eleTime = node.firstChildElement(TIME);
|
||||
if (!eleTime.isNull())
|
||||
backupPoint.m_time = eleTime.text();
|
||||
|
||||
QDomElement eleSize = node.firstChildElement(SIZE);
|
||||
if (!eleSize.isNull())
|
||||
backupPoint.m_size = eleSize.text();
|
||||
|
||||
QDomElement eleState = node.firstChildElement(STATE);
|
||||
if (!eleState.isNull())
|
||||
backupPoint.m_state = eleState.text();
|
||||
|
||||
QDomElement eleType = node.firstChildElement(TYPE);
|
||||
if (!eleType.isNull())
|
||||
backupPoint.m_type = eleType.text().toInt();
|
||||
|
||||
QDomElement elePosition = node.firstChildElement(POSITION);
|
||||
if (!elePosition.isNull())
|
||||
backupPoint.m_iPosition = elePosition.text().toInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief backupPoint --> ElementNode
|
||||
* @param backupPoint, BackupPoint
|
||||
* @param node, QDomElement
|
||||
*/
|
||||
void ParseBackupList::backupPointToElementNode(const BackupPoint& backupPoint, QDomElement& 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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief createTextElement
|
||||
* @param tagName
|
||||
* @param text
|
||||
* @return <tagName>text</tagName>
|
||||
*/
|
||||
QDomElement ParseBackupList::createTextElement(const QString& tagName, const QString& text)
|
||||
{
|
||||
QDomElement node;
|
||||
node.setTagName(tagName);
|
||||
QDomText textNode;
|
||||
textNode.setData(text);
|
||||
node.appendChild(textNode);
|
||||
|
||||
return node;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef PARSEBACKUPLIST_H
|
||||
#define PARSEBACKUPLIST_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include "../common/mydefine.h"
|
||||
|
||||
class ParseBackupList {
|
||||
public:
|
||||
enum ParseResult {
|
||||
// xml解析错误
|
||||
XML_PARSE_ERR,
|
||||
// 失败
|
||||
FAIL,
|
||||
// 成功
|
||||
SUCCESS,
|
||||
};
|
||||
|
||||
struct BackupPoint {
|
||||
// 备份或还原指定的UUID
|
||||
QString m_uuid;
|
||||
// 备份名称,用来替换m_comment
|
||||
QString m_backupName;
|
||||
// 备份时间
|
||||
QString m_time;
|
||||
// 本地备份还是U盘备份: 0-本地备份;1-移动设备备份
|
||||
int m_iPosition = -1;
|
||||
// 操作类型,如:系统备份, 系统还原
|
||||
int m_type = -1;
|
||||
// 备份大小
|
||||
QString m_size;
|
||||
// 备份状态,如是否完成
|
||||
QString m_state;
|
||||
|
||||
bool isNull() { return m_uuid.isEmpty(); }
|
||||
};
|
||||
|
||||
ParseBackupList(const QString& xmlPath);
|
||||
|
||||
/**
|
||||
* @brief 出厂备份修改backuplist.xml,仅保留出厂备份信息
|
||||
* @param factoryBackupUuid,出厂备份的uuid
|
||||
* @return ParseResult枚举类型
|
||||
* @author zhaominyong
|
||||
* @since 2021/06/27
|
||||
*/
|
||||
ParseResult updateForFactoryRestore(const QString &factoryBackupUuid);
|
||||
|
||||
/**
|
||||
* @brief 根据comment查找uuid
|
||||
* @param comment
|
||||
* @return uuid
|
||||
*/
|
||||
QString findUuidByComment(const QString& comment);
|
||||
|
||||
/**
|
||||
* @brief 根据Uuid查找备份点信息
|
||||
* @param Uuid
|
||||
* @return 备份点信息
|
||||
*/
|
||||
BackupPoint findBackupPointByUuid(const QString& Uuid);
|
||||
|
||||
/**
|
||||
* @brief 获取最后一次系统备份
|
||||
* @return
|
||||
*/
|
||||
BackupPoint getLastSysBackupPoint();
|
||||
|
||||
inline QString getXmlPath() { return m_xmlPath; }
|
||||
|
||||
private:
|
||||
bool InitXml();
|
||||
bool isXmlCorrect();
|
||||
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);
|
||||
|
||||
private:
|
||||
QString m_xmlPath;
|
||||
};
|
||||
|
||||
#endif // PARSEBACKUPLIST_H
|
|
@ -1,20 +1,40 @@
|
|||
#include "systembackupproxy.h"
|
||||
#include <QStorageInfo>
|
||||
#include <QDebug>
|
||||
#include "../common/utils.h"
|
||||
#include "../common/mydusizetool.h"
|
||||
#include "mymountproxy.h"
|
||||
#include "parsebackuplist.h"
|
||||
|
||||
IMPLEMENT_DYNCREATE(SystemBackupProxy)
|
||||
|
||||
SystemBackupProxy::SystemBackupProxy(QObject * parent) :
|
||||
Worker(parent)
|
||||
SystemBackupProxy::SystemBackupProxy()
|
||||
{}
|
||||
|
||||
SystemBackupProxy::~SystemBackupProxy()
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief 环境检测
|
||||
*/
|
||||
void SystemBackupProxy::checkEnvEx()
|
||||
{
|
||||
qDebug() << "SystemBackupProxy::checkEnv invoke begin";
|
||||
emit checkResult((int)BackupResult::BACKUP_START_SUCCESS);
|
||||
|
||||
// 1、检查/backup分区是否挂载上(不管是本地磁盘还是u盘设备,都得保证/backup挂载上); 若没挂载,挂载
|
||||
MyMountProxy mountProxy;
|
||||
if ( MyMountProxy::MountResult::MOUNTED != mountProxy.mountBackupPartition() ) {
|
||||
emit checkResult(int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL));
|
||||
return ;
|
||||
}
|
||||
|
||||
// 2、检测备份是否增量备份
|
||||
bool bInc = checkIsIncBackup();
|
||||
m_backupWrapper.m_bIncrement = bInc;
|
||||
|
||||
// 3、检测空间是否满足备份
|
||||
checkFreeCapacity(bInc);
|
||||
|
||||
qDebug() << "SystemBackupProxy::checkEnv invoke end";
|
||||
}
|
||||
|
||||
|
@ -24,3 +44,83 @@ void SystemBackupProxy::doWorkEx()
|
|||
void SystemBackupProxy::cancelEx()
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief 校验是否增量备份
|
||||
* @return true,增量备份; false,全量备份
|
||||
*/
|
||||
bool SystemBackupProxy::checkIsIncBackup()
|
||||
{
|
||||
QString backupPath;
|
||||
if (m_backupWrapper.m_uuid.isEmpty()) {
|
||||
QString xmlPath(Utils::getSysRootPath() + BACKUP_XML_PATH);
|
||||
xmlPath.replace("//", "/");
|
||||
ParseBackupList parser(xmlPath);
|
||||
ParseBackupList::BackupPoint point = parser.getLastSysBackupPoint();
|
||||
if (point.m_uuid.isEmpty())
|
||||
return false;
|
||||
backupPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + point.m_uuid + "/data";
|
||||
} else {
|
||||
backupPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data";
|
||||
}
|
||||
|
||||
backupPath.replace("//", "/");
|
||||
return Utils::isDirExist(backupPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 校验剩余空间是否满足备份
|
||||
* @param bInc,是否增量备份
|
||||
* @note 增量备份和全量备份计算空间方法不同
|
||||
*/
|
||||
void SystemBackupProxy::checkFreeCapacity(bool bInc)
|
||||
{
|
||||
// 1、计算待备份数据的大小
|
||||
MyDuSizeTool du;
|
||||
qint64 itotalSize = du.Do(m_backupWrapper.m_backupPaths, m_backupWrapper.m_backupExcludePaths, true);
|
||||
if (-1 == itotalSize) {
|
||||
qCritical() << "du system backup failed";
|
||||
emit checkResult(int(BackupResult::DU_ERR));
|
||||
return ;
|
||||
}
|
||||
|
||||
// 2、计算备份分区剩余空间大小
|
||||
QString backupPath(Utils::getSysRootPath() + BACKUP_PATH);
|
||||
backupPath.replace("//", "/");
|
||||
QStorageInfo backupDisk(backupPath);
|
||||
qint64 freeSize = backupDisk.bytesFree();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据场景获取rsync命令参数
|
||||
* @param scene,场景
|
||||
* @return rsync的参数信息
|
||||
*/
|
||||
QStringList SystemBackupProxy::getRsyncArgs(SystemBackupScene scene)
|
||||
{
|
||||
QStringList args;
|
||||
|
||||
switch (scene) {
|
||||
case SystemBackupScene::SYSTEM_BACKUP :
|
||||
args << "-avAXW";
|
||||
args << "--progress";
|
||||
break ;
|
||||
case SystemBackupScene::INC_SYSTEM_BACKUP :
|
||||
args << "-avAXr";
|
||||
args << "--progress";
|
||||
args << "--link-dest";
|
||||
break ;
|
||||
case SystemBackupScene::TRY_SYSTEM_BACKUP :
|
||||
args << "-avAXWn";
|
||||
args << "--stats";
|
||||
break ;
|
||||
case SystemBackupScene::TRY_INC_SYSTEM_BACKUP :
|
||||
args << "-avAXrn";
|
||||
args << "--stats";
|
||||
args << "--link-dest";
|
||||
break ;
|
||||
default:
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,15 @@ class SystemBackupProxy : public Worker
|
|||
Q_OBJECT
|
||||
DECLARE_DYNCREATE(SystemBackupProxy)
|
||||
public:
|
||||
SystemBackupProxy(QObject * parent = nullptr);
|
||||
// 系统备份的几种场景
|
||||
enum SystemBackupScene {
|
||||
SYSTEM_BACKUP, // 系统备份
|
||||
INC_SYSTEM_BACKUP, // 增量系统备份
|
||||
TRY_SYSTEM_BACKUP, // 测试系统备份,可用于计算备份传输数据大小
|
||||
TRY_INC_SYSTEM_BACKUP, // 测试增量系统备份,可用于计算备份传输数据大小
|
||||
};
|
||||
|
||||
explicit SystemBackupProxy();
|
||||
virtual ~SystemBackupProxy();
|
||||
|
||||
public:
|
||||
|
@ -20,6 +28,23 @@ public:
|
|||
|
||||
// 任务取消
|
||||
virtual void cancelEx();
|
||||
|
||||
private:
|
||||
// 校验是否增量备份
|
||||
bool checkIsIncBackup();
|
||||
|
||||
// 校验剩余空间是否满足备份
|
||||
void checkFreeCapacity(bool bInc);
|
||||
|
||||
/**
|
||||
* @brief 根据场景获取rsync命令参数
|
||||
* @param scene,场景
|
||||
* @return 组装好的rsync的参数信息
|
||||
*/
|
||||
QString getRsyncArgs(SystemBackupScene scene);
|
||||
|
||||
// 是否增量备份
|
||||
bool m_bIncrement = false;
|
||||
};
|
||||
|
||||
#endif // SYSTEMBACKUPPROXY_H
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "workerfactory.h"
|
||||
#include <QString>
|
||||
|
||||
Worker::Worker(QObject* parent) :
|
||||
QObject(parent)
|
||||
Worker::Worker() :
|
||||
QObject(nullptr)
|
||||
{}
|
||||
|
||||
Worker::~Worker()
|
||||
|
|
|
@ -12,7 +12,7 @@ class Worker : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Worker(QObject* parent = nullptr);
|
||||
explicit Worker();
|
||||
virtual ~Worker();
|
||||
|
||||
signals:
|
||||
|
|
|
@ -8,19 +8,16 @@
|
|||
|
||||
#define DEFAULT_APP_PATH "/usr/bin"
|
||||
|
||||
#define LOCK_FILE "/tmp/lock/kylin-backup.lock"
|
||||
|
||||
#define BACKUP_XML_PATH "/backup/snapshots/backuplist.xml"
|
||||
|
||||
#define BOOTINFO_PATH "/etc/.bootinfo"
|
||||
|
||||
#define BACKUP_PATH "/backup"
|
||||
|
||||
#define BACKUP_SNAPSHOTS_PATH "/backup/snapshots"
|
||||
|
||||
#define BACKUP_XML_PATH "/backup/snapshots/backuplist.xml"
|
||||
#define EXCLUDE_FILE_PATH "/backup/snapshots/.exclude"
|
||||
|
||||
#define BOOTINFO_PATH "/etc/.bootinfo"
|
||||
#define FSTAB_PATH "/etc/fstab"
|
||||
#define LOCK_FILE "/tmp/lock/kylin-backup.lock"
|
||||
#define LOCK_FILE_PATH "/tmp/lock"
|
||||
#define PROC_LOG "/var/log/backup.log"
|
||||
|
||||
#define BACKUP_CLI_NAME "kybackup"
|
||||
|
||||
|
@ -83,6 +80,8 @@ struct BackupWrapper {
|
|||
int m_frontUid = -1;
|
||||
// 备份用户所属组id
|
||||
int m_gid = -1;
|
||||
// 是否增量备份
|
||||
bool m_bIncrement = false;
|
||||
|
||||
static void registerMetaType();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#include "mydusizetool.h"
|
||||
#include <QDebug>
|
||||
#include "utils.h"
|
||||
|
||||
MyDuSizeTool::MyDuSizeTool(QObject* parent)
|
||||
{
|
||||
m_p = new QProcess(this);
|
||||
connect(m_p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
|
||||
connect(m_p, &QProcess::readyReadStandardError, this, [&]() {
|
||||
QByteArray err = m_p->readAllStandardError();
|
||||
qCritical("du process error: %s", err.data());
|
||||
});
|
||||
}
|
||||
|
||||
MyDuSizeTool::~MyDuSizeTool()
|
||||
{
|
||||
delete m_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MyDuSizeTool::Do
|
||||
* @param paths, du计算路径列表
|
||||
* @param excludePaths,du排查路径列表
|
||||
* @param block,bool, 是否阻塞方式计算
|
||||
* @return
|
||||
*/
|
||||
qint64 MyDuSizeTool::Do(QStringList paths, QStringList excludePaths, bool block)
|
||||
{
|
||||
return _Do(paths, excludePaths, true, block);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MyDuSizeTool::_Do
|
||||
* @param paths, du计算路径列表
|
||||
* @param excludePaths,du排查路径列表
|
||||
* @param needExclude,bool,是否需要排除
|
||||
* @param block,bool, 是否阻塞方式计算
|
||||
* @return
|
||||
*/
|
||||
qint64 MyDuSizeTool::_Do(QStringList paths, QStringList excludePaths, bool needExclude, bool block)
|
||||
{
|
||||
Init(paths, excludePaths);
|
||||
|
||||
if (paths.isEmpty()) {
|
||||
qCritical("du paths is empty!");
|
||||
return -1;
|
||||
}
|
||||
if (needExclude && excludePaths.isEmpty()) {
|
||||
qCritical("du excludepaths is empty!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString cmd = "du";
|
||||
for (QString& x : paths) {
|
||||
cmd.append(QString(" \"%1\"").arg(x));
|
||||
}
|
||||
if (needExclude) {
|
||||
for (QString& item : excludePaths) {
|
||||
QString arg = QString(" --exclude=\"%1\"").arg(x);
|
||||
cmd.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
cmd.append(" -sb | tail -1 | awk -F \" \" '{print $1}'");
|
||||
|
||||
qDebug("cmd is %s", cmd.toStdString().c_str());
|
||||
|
||||
QStringList Args;
|
||||
Args << "-c" << cmd;
|
||||
m_p->start("bash", Args);
|
||||
|
||||
if (!m_p->waitForStarted())
|
||||
return -1;
|
||||
|
||||
if (block) {
|
||||
if (!m_p->waitForFinished(-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MyDuSizeTool::Do
|
||||
* @param paths, du计算路径列表
|
||||
* @param excludePaths,du排查路径列表
|
||||
* @param block,bool, 是否阻塞方式计算
|
||||
* @return
|
||||
*/
|
||||
qint64 MyDuSizeTool::Do(QStringList paths, bool block)
|
||||
{
|
||||
return _Do(paths, {}, false, block);
|
||||
}
|
||||
|
||||
void MyDuSizeTool::Init(QStringList paths, QStringList excludePaths)
|
||||
{
|
||||
m_paths = paths;
|
||||
m_excludePaths = excludePaths;
|
||||
}
|
||||
|
||||
void MyDuSizeTool::finished(int, QProcess::ExitStatus)
|
||||
{
|
||||
QString result = m_p->readAll();
|
||||
if (result.isEmpty())
|
||||
m_size = 0;
|
||||
else
|
||||
m_size = result.toLongLong();
|
||||
emit duFinished(m_size);
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef MYDUSIZETOOL_H
|
||||
#define MYDUSIZETOOL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
class MyDuSizeTool : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyDuSizeTool(QObject* parent = nullptr);
|
||||
~MyDuSizeTool();
|
||||
|
||||
qint64 Do(QStringList paths, QStringList excludePaths, bool block = true);
|
||||
qint64 Do(QStringList paths, bool block = true);
|
||||
qint64 size() { return m_size; }
|
||||
|
||||
private:
|
||||
void Init(QStringList paths, QStringList excludePaths);
|
||||
qint64 _Do(QStringList paths, QStringList excludePaths, bool needExclude, bool block = true);
|
||||
|
||||
signals:
|
||||
void duFinished(qint64 size);
|
||||
private slots:
|
||||
void finished(int, QProcess::ExitStatus);
|
||||
|
||||
private:
|
||||
QStringList m_paths;
|
||||
QStringList m_excludePaths;
|
||||
qint64 m_size = 0;
|
||||
|
||||
QProcess* m_p;
|
||||
};
|
||||
|
||||
#endif // !MYDUSIZETOOL_H
|
104
common/utils.cpp
104
common/utils.cpp
|
@ -5,6 +5,7 @@
|
|||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QRegularExpression>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -66,13 +67,13 @@ void Utils::customMessageHandler(QtMsgType type, const QMessageLogContext& conte
|
|||
|
||||
// 设置输出信息格式
|
||||
QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
|
||||
QString strMessage = strMsg + QString("DateTime:%1 Message:%2 File:%3(%4)")
|
||||
.arg(strDateTime).arg(localMsg.constData()).arg(context.file).arg(context.line);
|
||||
QString strMessage = strMsg + QString("DateTime:%1 ThreadId:%2 Message:%3 File:%4(%5)")
|
||||
.arg(strDateTime).arg(QString::number(quintptr(QThread::currentThreadId()))).arg(localMsg.constData()).arg(context.file).arg(context.line);
|
||||
|
||||
std::cout << strMessage.toUtf8().data() << std::endl;
|
||||
|
||||
// 输出信息至文件中(读写、追加形式)
|
||||
QString fileName = m_sysRootPath + "/var/log/backup.log";
|
||||
QString fileName = m_sysRootPath + PROC_LOG;
|
||||
fileName.replace("//", "/");
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::ReadWrite | QIODevice::Append);
|
||||
|
@ -91,10 +92,10 @@ void Utils::customMessageHandler(QtMsgType type, const QMessageLogContext& conte
|
|||
*/
|
||||
int Utils::lockProgram(int frontUid)
|
||||
{
|
||||
QDir dir("/tmp/lock");
|
||||
QDir dir(LOCK_FILE_PATH);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdir("/tmp/lock");
|
||||
chmod("/tmp/lock", S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
dir.mkdir(LOCK_FILE_PATH);
|
||||
chmod(LOCK_FILE_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
}
|
||||
|
||||
int lock_file_fd = ::open(LOCK_FILE, O_CREAT | O_RDWR, 0666);
|
||||
|
@ -169,7 +170,7 @@ bool Utils::checkBootInfoExists()
|
|||
|
||||
/**
|
||||
* @brief 获取备份分区的UUID
|
||||
* @return
|
||||
* @return 备份分区的UUID
|
||||
*/
|
||||
QString Utils::getBackupPartitionUuid()
|
||||
{
|
||||
|
@ -252,7 +253,7 @@ void Utils::excludeFstabBindPath(QStringList &excludes)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 生成rsync --exclude路径规则文件
|
||||
* @brief 生成rsync --exclude-from排除路径规则文件
|
||||
* @return
|
||||
*/
|
||||
bool Utils::generateExcludePathsFile()
|
||||
|
@ -270,25 +271,25 @@ bool Utils::generateExcludePathsFile()
|
|||
QTextStream in(&excludePathFile);
|
||||
in << "/backup" << endl; //分区
|
||||
in << "/boot/efi" << endl;
|
||||
in << "/cdrom" << endl;
|
||||
in << "/dev" << endl;
|
||||
// efi原始目录在/boot/efi,备份到目标目录为/efi下,再还原时已经单独处理了,批量还原时应该屏蔽此目录
|
||||
in << "/efi" << endl;
|
||||
in << "/dev/*" << endl;
|
||||
in << "/ghost" << endl; //ghost镜像文件
|
||||
in << "/mnt/*" << endl;
|
||||
in << "/proc/*" << endl;
|
||||
in << "/run/*" << endl;
|
||||
in << "/sys/*" << endl; //添加*,表示如果/sys目录不存在,则会拷贝/sys,但不会拷贝/sys下的内容
|
||||
in << "/media/*" << endl;
|
||||
in << "/tmp/*" << endl;
|
||||
in << "/lost+found/*" << endl;
|
||||
in << "/var/lib/udisks2/*" << endl;
|
||||
in << "/cdrom/*" << endl;
|
||||
in << "/swap_file" << endl;
|
||||
// 安全模块会将文件/usr/share/kysec-utils/data/readonly_list中的文件列表限制只读,无法修改、备份(包含扩展属性时)、删除等
|
||||
// 现在里面仅有/etc/uid_list,先暂时排除掉;等后续安全模块有其它保护方案后再进一步修改
|
||||
in << "/etc/uid_list" << endl;
|
||||
in << "/ghost" << endl; //ghost镜像文件
|
||||
in << "/lost+found" << endl;
|
||||
in << "/media" << endl;
|
||||
in << "/mnt" << endl;
|
||||
in << "/proc" << endl;
|
||||
in << "/run" << endl;
|
||||
in << "/swap_file" << endl;
|
||||
in << "/sys" << endl; //添加*(/sys/*),表示如果/sys目录不存在,则会拷贝/sys,但不会拷贝/sys下的内容
|
||||
in << "/tmp" << endl;
|
||||
// 安卓兼容的这个里面很多文件都是设置了特殊扩展文件属性,lsetxattr无法设置成功,听取安卓兼容模块同事的意见不用管这个文件夹,其实是从home下挂载的
|
||||
in << "/var/lib/kmre" << endl;
|
||||
in << "/var/lib/udisks2" << endl;
|
||||
in << "/var/log" << endl;
|
||||
|
||||
// 系统安装后有的会将/data/home /data/root挂载到的/home /root上,实际文件是存放在/data/home /data/root下面
|
||||
|
@ -302,3 +303,66 @@ bool Utils::generateExcludePathsFile()
|
|||
excludePathFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断目录是否存在
|
||||
* @param 目录路径
|
||||
* @return true,存在;false,不存在
|
||||
*/
|
||||
bool Utils::isDirExist(const QString& fullDirName)
|
||||
{
|
||||
QDir dir(fullDirName);
|
||||
if (dir.exists())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取系统备份还原排除路径列表, rsync --exclude-from排除路径规则文件中读取
|
||||
* @return 系统备份还原排除路径列表
|
||||
*/
|
||||
QStringList Utils::getFromExcludePathsFile()
|
||||
{
|
||||
QString excludeFile = Utils::m_sysRootPath + EXCLUDE_FILE_PATH;
|
||||
excludeFile.replace("//", "/");
|
||||
QFile excludePathFile(excludeFile);
|
||||
if (!excludePathFile.open(QIODevice::ReadOnly)) {
|
||||
QStringList list;
|
||||
list << "/backup";
|
||||
list << "/boot/efi";
|
||||
list << "/cdrom";
|
||||
list << "/dev";
|
||||
list << "/efi";
|
||||
list << "/etc/uid_list";
|
||||
list << "/ghost";
|
||||
list << "/lost+found";
|
||||
list << "/media";
|
||||
list << "/mnt";
|
||||
list << "/proc";
|
||||
list << "/run";
|
||||
list << "/swap_file";
|
||||
list << "/sys";
|
||||
list << "/tmp";
|
||||
list << "/var/lib/kmre";
|
||||
list << "/var/lib/udisks2";
|
||||
list << "/var/log";
|
||||
|
||||
// 系统安装后有的会将/data/home /data/root挂载到的/home /root上,实际文件是存放在/data/home /data/root下面
|
||||
QStringList excludes;
|
||||
Utils::excludeFstabBindPath(excludes);
|
||||
for (const QString& item : excludes) {
|
||||
list << item;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QTextStream out(&excludePathFile);
|
||||
QString strAll = out.readAll();
|
||||
excludePathFile.close();
|
||||
|
||||
QStringList list = strAll.split("\n");
|
||||
list.removeAll(QString(""));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -87,11 +87,24 @@ public:
|
|||
static void excludeFstabBindPath(QStringList &excludes);
|
||||
|
||||
/**
|
||||
* @brief 生成rsync --exclude路径规则文件
|
||||
* @brief 生成rsync --exclude-from排除路径规则文件
|
||||
* @return
|
||||
*/
|
||||
static bool generateExcludePathsFile();
|
||||
|
||||
/**
|
||||
* @brief 获取系统备份还原排除路径列表
|
||||
* @return 系统备份还原排除路径列表
|
||||
*/
|
||||
static QStringList getFromExcludePathsFile();
|
||||
|
||||
/**
|
||||
* @brief 判断目录是否存在
|
||||
* @param 目录路径
|
||||
* @return true,存在;false,不存在
|
||||
*/
|
||||
static bool isDirExist(const QString& fullDirName);
|
||||
|
||||
private:
|
||||
// 系统根目录,默认"/"
|
||||
static QString m_sysRootPath;
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.11.0, 2021-08-16T15:03:50. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{d6d3c1b3-be59-4e12-87de-c60657210d67}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap"/>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">桌面</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">桌面</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{5440484b-1916-43f8-99de-3fbc4fe13c66}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/zhaominyong/workspace/kylin-backup-tools-new/build-yhkylin-backup-tool-unknown-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.BuildTargets"/>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
||||
<value type="QString">-e</value>
|
||||
<value type="QString">cpu-cycles</value>
|
||||
<value type="QString">--call-graph</value>
|
||||
<value type="QString">dwarf,4096</value>
|
||||
<value type="QString">-F</value>
|
||||
<value type="QString">250</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/zhaominyong/workspace/kylin-backup-tools-new/kylin-backup-tools-4.0.14/backup-daemon/backup-daemon.pro</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/zhaominyong/workspace/kylin-backup-tools-new/kylin-backup-tools-4.0.14/backup-daemon/backup-daemon.pro</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
|
||||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/zhaominyong/workspace/kylin-backup-tools-new/build-yhkylin-backup-tool-unknown-Debug/backup-daemon</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
||||
<value type="QString">-e</value>
|
||||
<value type="QString">cpu-cycles</value>
|
||||
<value type="QString">--call-graph</value>
|
||||
<value type="QString">dwarf,4096</value>
|
||||
<value type="QString">-F</value>
|
||||
<value type="QString">250</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/zhaominyong/workspace/kylin-backup-tools-new/kylin-backup-tools-4.0.14/kybackup/kybackup.pro</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/zhaominyong/workspace/kylin-backup-tools-new/kylin-backup-tools-4.0.14/kybackup/kybackup.pro</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
|
||||
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/zhaominyong/workspace/kylin-backup-tools-new/build-yhkylin-backup-tool-unknown-Debug/kybackup</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
</qtcreator>
|
Loading…
Reference in New Issue