File indexing completed on 2024-04-28 05:45:54

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2014-2018 Andrius Štikonas <andrius@stikonas.eu>
0004 
0005     SPDX-License-Identifier: GPL-3.0-or-later
0006 */
0007 
0008 #include "jobs/restorefilesystemjob.h"
0009 
0010 #include "backend/corebackend.h"
0011 #include "backend/corebackendmanager.h"
0012 #include "backend/corebackenddevice.h"
0013 #include "backend/corebackendpartitiontable.h"
0014 
0015 #include "core/partition.h"
0016 #include "core/device.h"
0017 #include "core/copysourcefile.h"
0018 #include "core/copytargetdevice.h"
0019 
0020 #include "fs/filesystem.h"
0021 #include "fs/filesystemfactory.h"
0022 
0023 #include "util/report.h"
0024 
0025 #include <KLocalizedString>
0026 
0027 /** Creates a new RestoreFileSystemJob
0028     @param targetdevice the Device the FileSystem is to be restored to
0029     @param targetpartition the Partition the FileSystem is to be restore to
0030     @param filename the file name with the image file to restore
0031 */
0032 RestoreFileSystemJob::RestoreFileSystemJob(Device& targetdevice, Partition& targetpartition, const QString& filename) :
0033     Job(),
0034     m_TargetDevice(targetdevice),
0035     m_TargetPartition(targetpartition),
0036     m_FileName(filename)
0037 {
0038 }
0039 
0040 qint32 RestoreFileSystemJob::numSteps() const
0041 {
0042     return 100;
0043 }
0044 
0045 bool RestoreFileSystemJob::run(Report& parent)
0046 {
0047     // Restoring is file system independent because we currently have no way of
0048     // detecting the file system in a given image file. We cannot even find out if the
0049     // file the user gave us is a valid image file or just some junk.
0050 
0051     bool rval = false;
0052 
0053     Report* report = jobStarted(parent);
0054 
0055     // Again, a scope for copyTarget and copySource. See MoveFileSystemJob::run()
0056     {
0057         // FileSystems are restored to _partitions_, so don't use first and last sector of file system here
0058         CopyTargetDevice copyTarget(targetDevice(), targetPartition().firstByte(), targetPartition().lastByte());
0059         CopySourceFile copySource(fileName());
0060 
0061         if (!copySource.open())
0062             report->line() << xi18nc("@info:progress", "Could not open backup file <filename>%1</filename> to restore from.", fileName());
0063         else if (!copyTarget.open())
0064             report->line() << xi18nc("@info:progress", "Could not open target partition <filename>%1</filename> to restore to.", targetPartition().deviceNode());
0065         else {
0066             rval = copyBlocks(*report, copyTarget, copySource);
0067 
0068             if (rval) {
0069                 // create a new file system for what was restored with the length of the image file
0070                 const qint64 newLastSector = targetPartition().firstSector() + copySource.length() - 1;
0071 
0072                 std::unique_ptr<CoreBackendDevice> backendDevice = CoreBackendManager::self()->backend()->openDevice(targetDevice());
0073 
0074                 FileSystem::Type t = FileSystem::Type::Unknown;
0075 
0076                 if (backendDevice) {
0077                     std::unique_ptr<CoreBackendPartitionTable> backendPartitionTable = backendDevice->openPartitionTable();
0078 
0079                     if (backendPartitionTable)
0080                         t = backendPartitionTable->detectFileSystemBySector(*report, targetDevice(), targetPartition().firstSector());
0081                 }
0082 
0083                 FileSystem* fs = FileSystemFactory::create(t, targetPartition().firstSector(), newLastSector, targetPartition().sectorSize());
0084 
0085                 targetPartition().deleteFileSystem();
0086                 targetPartition().setFileSystem(fs);
0087             }
0088 
0089             report->line() << xi18nc("@info:progress", "Closing device. This may take a few seconds.");
0090         }
0091     }
0092 
0093     jobFinished(*report, rval);
0094 
0095     return rval;
0096 }
0097 
0098 QString RestoreFileSystemJob::description() const
0099 {
0100     return xi18nc("@info:progress", "Restore the file system from file <filename>%1</filename> to partition <filename>%2</filename>", fileName(), targetPartition().deviceNode());
0101 }