#include "ghostimageproxy.h" #include #include #include #include #include #include #include "../common/utils.h" #include "../common/mydusizetool.h" #include "mymountproxy.h" #include "myprocess/calcbackupsize.h" IMPLEMENT_DYNCREATE(GhostImageProxy) GhostImageProxy::GhostImageProxy() { m_mksquashfs = nullptr; m_bSuccess = false; m_isFinished = false; connect(this, &GhostImageProxy::cancel, this, &GhostImageProxy::cancelEx); } GhostImageProxy::~GhostImageProxy() { delete m_mksquashfs; m_mksquashfs = nullptr; } /** * @brief 环境检测 */ bool GhostImageProxy::checkEnvEx() { // 1、检查/backup分区是否挂载上(不管是本地磁盘还是u盘设备,都得保证/backup挂载上); 若没挂载,挂载 MyMountProxy mountProxy; if ( MountResult::MOUNTED != mountProxy.mountBackupPartition() ) { emit checkResult(int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL)); return false; } // 2、校验backuppoint.xml中相应的备份节点是否存在 QString xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH; xmlPath.replace("//", "/"); ParseBackupList xmlParse(xmlPath); ParseBackupList::BackupPoint backupPoint = xmlParse.findBackupPointByUuid(m_backupWrapper.m_uuid); if (backupPoint.m_backupName.isEmpty()) { emit checkResult(int(BackupResult::GHOST_CANNOT_FIND_BACKUPPOINT)); return false; } // 3、校验备份数据是否存在 QString dataPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data"; dataPath.replace("//", "/"); if (Utils::isDirEmpty(dataPath)) { emit checkResult(int(BackupResult::GHOST_SRC_DIRECTORY_IS_NOT_EXIST)); return false; } QFileInfo backup(dataPath); qint64 itotalSize = backup.size(); // 4、校验空间大小是否充足 m_destPath = Utils::getSysRootPath() + GHOST_PATH; m_destPath.replace("//", "/"); Utils::mkpath(m_destPath); m_kyimg = Utils::getSysRootPath() + GHOST_PATH + "/" + m_backupWrapper.m_backupName; m_kyimg.replace("//", "/"); QFile kyimg(m_kyimg); if (kyimg.exists()) kyimg.remove(); QStorageInfo storageInfo(m_destPath); qint64 sizeAvailable = storageInfo.bytesAvailable(); if (sizeAvailable < itotalSize / 2) { emit checkResult(int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH)); return false; } emit checkResult(int(BackupResult::CHECK_ENV_SUCCESS)); return true; } /** * @brief 任务处理 */ void GhostImageProxy::doWorkEx() { if (!checkEnvEx()) return ; doGhostImage(); } /** * @brief 任务取消 */ void GhostImageProxy::cancelEx() { m_bCancel = true; if (!m_isFinished) { emit this->checkResult(int(BackupResult::START_CANCEL)); if (m_mksquashfs) m_mksquashfs->stop(); QProcess::execute("sync"); Utils::wait(5); deleteFailedData(); emit this->checkResult(int(BackupResult::CANCEL_SUCCESS)); } } /** * @brief 失败则删除相应数据 */ void GhostImageProxy::deleteFailedData() { // 1、删除镜像文件 QFile kyimg(m_kyimg); if (kyimg.exists()) kyimg.remove(); } /** * @brief ghost镜像 */ void GhostImageProxy::doGhostImage() { QStringList args; // 拼接备份源路径和目标路径 QString srcPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid + "/data"; srcPath.replace("//", "/"); args << srcPath; args << m_kyimg; m_mksquashfs = new MkSquashFSProcess(this); connect(m_mksquashfs, &MkSquashFSProcess::progress, this, &GhostImageProxy::progress); connect(m_mksquashfs, &MkSquashFSProcess::finished, this, [&](bool result) { // 如果是取消了操作,则不再发送其它信息 if (m_bCancel) return ; m_isFinished = true; if (result) { chown(m_kyimg.toLocal8Bit().data(), m_backupWrapper.m_frontUid, m_backupWrapper.m_gid); // QFileInfo fileInfo(m_kyimg); // QString imgSize = Utils::StringBySize(fileInfo.size()); // QString time = QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss"); // Utils::writeBackupLog(time + "," // + m_backupWrapper.m_uuid + "," + QString::number(m_backupWrapper.m_type) + "," // + m_backupWrapper.m_note + "," + imgSize // + ",," + m_backupWrapper.m_backupName); m_bSuccess = true; } emit this->workResult(result); }); m_bSuccess = false; m_mksquashfs->start(args); }