yhkylin-backup-tools/backup-daemon/mybackupmanager.cpp

519 lines
15 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* brief 程序比较小将接口层和控制层合到一起主要做一些任务分发状态监控等一些简单工作复杂的耗时的逻辑放到任务中moveToThread中去执行
*/
#include <QTimer>
#include <QDateTime>
#include <mutex>
#include <sys/reboot.h>
#include <kysec/status.h>
#include "mybackupmanager.h"
#include "../common/utils.h"
#include "mymountproxy.h"
#include "workerfactory.h"
#include "parsebackuplist.h"
/**
* @brief 构造函数
*/
MyBackupManager::MyBackupManager()
{
// 注册BackupWrapper类型之后qdbus接口才能使用
BackupWrapper::registerMetaType();
}
/**
* @brief 析构函数
*/
MyBackupManager::~MyBackupManager()
{
if (workerThread.isRunning()) {
workerThread.quit();
workerThread.wait();
}
}
/**
* @brief 挂载backup分区兼容提供给自动更新模块的老接口
* @return
*/
int MyBackupManager::Mount_backup_partition()
{
m_needUmount = false;
MyMountProxy mymount;
return int(mymount.mountBackupPartition());
}
/**
* @brief 卸载backup分区
* @return
*/
bool MyBackupManager::umountBackupPartition()
{
m_needUmount = true;
return umountBackup();
}
/**
* @brief 卸载backup分区
* @return
*/
bool MyBackupManager::umountBackup()
{
// /backup分区卸载
if (m_needUmount && m_isActive) {
QTimer::singleShot(5*1000, this, &MyBackupManager::umountBackup);
return true;
} else if (m_needUmount) {
MyMountProxy mymount;
return mymount.umountBackupPartition();
}
return true;
}
/**
* @brief 环境检测
* @param backupWrapper参数
* @return 0正确启动非0出现错误
*/
int MyBackupManager::checkEnv(const BackupWrapper& backupWrapper)
{
qDebug("MyBackupManager::checkEnv invoke begin");
if (m_isActive || !lock(backupWrapper.m_frontUid)) {
emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return int(BackupResult::LOCK_PROGRAM_FAIL);
}
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS));
return int(BackupResult::NO_FOUND_DEALCLASS);
}
worker->setParam(backupWrapper);
connect(worker, &Worker::checkResult, this, [&] (int result) {
emit this->sendEnvCheckResult(result);
this->finished();
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::checkEnv);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
workerThread.start();
qDebug("MyBackupManager::checkEnv invoke end");
return int(BackupResult::BACKUP_RESULT_INIT);
}
/**
* @brief 备份
* @param backupWrapper
* @return 0正确启动备份非0出现错误
*/
int MyBackupManager::goBackup(const BackupWrapper& backupWrapper)
{
qDebug("MyBackupManager::goBackup invoke begin");
if (m_isActive || !lock(backupWrapper.m_frontUid)) {
emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return int(BackupResult::LOCK_PROGRAM_FAIL);
}
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS));
return int(BackupResult::NO_FOUND_DEALCLASS);
}
worker->setParam(backupWrapper);
connect(worker, &Worker::checkResult, this, [&](int result) {
emit this->sendEnvCheckResult(result);
switch (result) {
case int(BackupResult::CHECK_ENV_SUCCESS) :
case int(BackupResult::MKSQUASHFS_START_SUCCESS) :
case int(BackupResult::BACKUP_START_SUCCESS) :
case int(BackupResult::START_CANCEL) :
break;
default:
this->finished();
break;
}
});
connect(worker, &Worker::progress, this, [&](int rate) {
emit this->progress(int(BackupState::WORKING), rate);
});
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->backupFinished(result);
this->finished();
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::doWork);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
connect(&workerThread, &MyThread::cancelWork, worker, &Worker::cancel);
workerThread.start();
qDebug("MyBackupManager::goBackup invoke end");
return int(BackupResult::BACKUP_RESULT_INIT);
}
/**
* @brief 还原
* @param backupWrapper
* @return
*/
int MyBackupManager::goRestore(const BackupWrapper& backupWrapper)
{
qDebug("MyBackupManager::goRestore invoke begin");
if (m_isActive || !lock(backupWrapper.m_frontUid)) {
emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return int(BackupResult::LOCK_PROGRAM_FAIL);
}
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS));
return int(BackupResult::NO_FOUND_DEALCLASS);
}
worker->setParam(backupWrapper);
connect(worker, &Worker::checkResult, this, [&](int result) {
emit this->sendEnvCheckResult(result);
switch (result) {
case int(BackupResult::CHECK_ENV_SUCCESS) :
case int(BackupResult::RESTORE_START_SUCCESS) :
break;
default:
this->finished();
break;
}
});
connect(worker, &Worker::progress, this, [&](int rate) {
emit this->progress(int(BackupState::WORKING), rate);
});
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->sendRestoreResult(result);
this->finished();
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::doWork);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
workerThread.start();
qDebug("MyBackupManager::goRestore invoke end");
return int(BackupResult::BACKUP_RESULT_INIT);
}
/**
* @brief 删除备份
* @param backupWrapper
* @return
*/
int MyBackupManager::deleteBackupPoint(const BackupWrapper& backupWrapper)
{
qDebug("MyBackupManager::deleteBackupPoint invoke begin");
if (m_isActive || !lock(backupWrapper.m_frontUid)) {
emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return int(BackupResult::LOCK_PROGRAM_FAIL);
}
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS));
return int(BackupResult::NO_FOUND_DEALCLASS);
}
worker->setParam(backupWrapper);
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->sendDeleteResult(result);
this->finished();
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::doWork);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
workerThread.start();
qDebug("MyBackupManager::deleteBackupPoint invoke end");
return int(BackupResult::BACKUP_RESULT_INIT);
}
/**
* @brief ghost镜像
* @param backupWrapper
* @return
*/
int MyBackupManager::ghostBackup(const BackupWrapper& backupWrapper)
{
qDebug("MyBackupManager::ghostBackup invoke begin");
if (m_isActive || !lock(backupWrapper.m_frontUid)) {
emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return int(BackupResult::LOCK_PROGRAM_FAIL);
}
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS));
return int(BackupResult::NO_FOUND_DEALCLASS);
}
worker->setParam(backupWrapper);
connect(worker, &Worker::checkResult, this, [&](int result) {
emit this->sendEnvCheckResult(result);
switch (result) {
case int(BackupResult::CHECK_ENV_SUCCESS) :
case int(BackupResult::GHOST_START_SUCCESS) :
case int(BackupResult::MKSQUASHFS_DO_SUCCESS) :
case int(BackupResult::START_CANCEL) :
break;
default:
this->finished();
break;
}
});
connect(worker, &Worker::progress, this, [&](int rate) {
emit this->progress(int(BackupState::WORKING), rate);
});
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->sendGhostBackupResult(result);
this->finished();
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::doWork);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
connect(&workerThread, &MyThread::cancelWork, worker, &Worker::cancel);
workerThread.start();
qDebug("MyBackupManager::ghostBackup invoke end");
return int(BackupResult::BACKUP_RESULT_INIT);
}
/**
* @brief 控制面板调用的备份接口,重构暂时先兼容以前的老接口
* @param autobackup_name 备份名称
* @param create_note 创建时备注
* @param inc_note 增量备注
* @param frontUserName 前端用户名
* @param frontUid 前端用户id
*/
void MyBackupManager::autoBackUpForSystemUpdate_noreturn(const QString& autobackup_name, const QString& create_note, const QString& inc_note, const QString& frontUserName, int frontUid)
{
qDebug("MyBackupManager::autoBackUpForSystemUpdate_noreturn invoke begin");
if (m_isActive || !lock(frontUid)) {
emit sendStartBackupResult(int(BackupResult::LOCK_PROGRAM_FAIL));
return ;
}
BackupWrapper backupWrapper;
backupWrapper.m_uuid = AUTO_BACKUP_UUID;
QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH;
xmlPath.replace("//", "/");
ParseBackupList parseXml(xmlPath);
ParseBackupList::BackupPoint backupPoint = parseXml.findBackupPointByUuid(backupWrapper.m_uuid);
if (autobackup_name.isEmpty()) {
if (backupPoint.m_backupName.isEmpty())
backupWrapper.m_backupName = QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss");
else
backupWrapper.m_backupName = backupPoint.m_backupName;
} else {
backupWrapper.m_backupName = autobackup_name;
}
backupWrapper.m_backupPaths << "/";
backupWrapper.m_backupExcludePaths = Utils::getFromExcludePathsFile();
backupWrapper.m_type = BackupType::BACKUP_SYSTEM;
backupWrapper.m_iPosition = BackupPosition::LOCAL;
backupWrapper.m_frontUserName = frontUserName;
backupWrapper.m_frontUid = frontUid;
backupWrapper.m_note = create_note.isEmpty() ? inc_note : create_note;
Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition);
if (nullptr == worker) {
emit sendStartBackupResult(int(BackupResult::NO_FOUND_DEALCLASS));
return ;
}
worker->setParam(backupWrapper);
connect(worker, &Worker::checkResult, this, [&](int result) {
emit this->sendStartBackupResult(result);
switch (result) {
case int(BackupResult::CHECK_ENV_SUCCESS) :
case int(BackupResult::MKSQUASHFS_START_SUCCESS) :
case int(BackupResult::BACKUP_START_SUCCESS) :
break;
default:
this->finished();
if (!Utils::isRunning("kybackup")) {
this->umountBackupPartition();
}
break;
}
});
connect(worker, &Worker::progress, this, [&](int rate) {
emit this->sendRate(int(BackupState::WORKING), rate);
});
connect(worker, &Worker::workResult, this, [&] (bool result) {
emit this->sendBackupResult(result);
this->finished();
if (!Utils::isRunning("kybackup")) {
this->umountBackupPartition();
}
});
worker->moveToThread(&workerThread);
connect(&workerThread, &MyThread::started, worker, &Worker::doWork);
connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater);
workerThread.start();
qDebug("MyBackupManager::autoBackUpForSystemUpdate_noreturn invoke end");
}
/**
* @brief 控制面板调用的获取系统备份接口
* @param state
* @return
*/
QString MyBackupManager::getBackupCommentForSystemUpdate(QString& state)
{
QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH;
xmlPath.replace("//", "/");
ParseBackupList parseXml(xmlPath);
ParseBackupList::BackupPoint backupPoint = parseXml.findBackupPointByUuid(AUTO_BACKUP_UUID);
state = backupPoint.m_state;
return backupPoint.m_backupName;
}
/**
* @brief 获取备份状态
* @param isActive是否活动状态
* @return
*/
int MyBackupManager::getBackupState(bool& isActive)
{
isActive = m_isActive;
return int(m_backupState);
}
/**
* @brief 取消操作
*/
int MyBackupManager::cancel()
{
if (workerThread.isRunning())
emit workerThread.cancelWork();
else
return 1;
return 0;
}
/**
* @brief 重启操作
* @return
*/
int MyBackupManager::reboot()
{
return ::reboot(RB_AUTOBOOT);;
}
/**
* @brief 任务结束
*/
void MyBackupManager::finished()
{
if (workerThread.isRunning()) {
workerThread.quit();
workerThread.wait();
}
unlock();
}
/**
* @brief 锁定应用
* @param frontUid锁定应用的用户id
* @return bool
*/
bool MyBackupManager::lock(int frontUid)
{
std::lock_guard<spinlock_mutex> lock(m_mutex);
int lock_file_fd = Utils::lockProgram(frontUid);
if (lock_file_fd < 0) {
Utils::rmLockFile();
return false;
}
m_fdLockFile = lock_file_fd;
m_backupState = BackupState::PREPARING;
m_isActive = true;
setKysecStatus(false);
return true;
}
/**
* @brief 解锁应用
* @return bool
*/
bool MyBackupManager::unlock()
{
std::lock_guard<spinlock_mutex> lock(m_mutex);
setKysecStatus(true);
Utils::unLockProgram(m_fdLockFile);
m_fdLockFile = -1;
m_backupState = BackupState::BACKUP_STATE_INIT;
m_isActive = false;
return true;
}
/**
* @brief 设置安全状态
* @param status,true-开启false-关闭
* @note status=true时不一定会开启取决于关闭时安全状态;
* 使用此方法时注意一定要先setKysecStatus(false);才能setKysecStatus(true);
* 使用场景:备份/还原等业务时先关闭安全保护,业务完成后再重启安全保护
*/
void MyBackupManager::setKysecStatus(bool status)
{
if (status) {
if (m_bOpenKysec)
Utils::setKysecStatus(true);
m_bOpenKysec = false;
if (m_bStartKysecDeamon)
Utils::setKysecDaemon(true);
m_bStartKysecDeamon = false;
} else {
if (KYSEC_STATUS_ENABLED == kysec_getstatus()) {
// 安全保护已开启
m_bOpenKysec = true;
Utils::setKysecStatus(false);
// 开启安全防护
// QProcess::execute("systemctl start kysec-init.service");
} else {
m_bOpenKysec = false;
}
if(Utils::isRunning("kysec-sync-daemon")){
m_bStartKysecDeamon = true;
Utils::setKysecDaemon(false);
// 停止安全防护
// QProcess::execute("systemctl stop kysec-init.service");
} else {
m_bStartKysecDeamon = false;
}
}
}