bool BackupFileSystemJob::run(Report& parent)
{
	bool rval = false;
	
	Report* report = jobStarted(parent);
	
	if (sourcePartition().fileSystem().supportBackup() == FileSystem::cmdSupportFileSystem)
		rval = sourcePartition().fileSystem().backup(*report, sourceDevice(), sourcePartition().deviceNode(), fileName());
	else if (sourcePartition().fileSystem().supportBackup() == FileSystem::cmdSupportCore)
	{
		CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstSector(), sourcePartition().fileSystem().lastSector());
		CopyTargetFile copyTarget(fileName(), sourceDevice().logicalSectorSize());

		if (!copySource.open())
			report->line() << i18nc("@info/plain", "Could not open file system on source partition <filename>%1</filename> for backup.", sourcePartition().deviceNode());
		else if (!copyTarget.open())
			report->line() << i18nc("@info/plain", "Could not create backup file <filename>%1</filename>.", fileName());
		else
			rval = copyBlocks(*report, copyTarget, copySource);
	}
	
	jobFinished(*report, rval);

	return rval;
}
Пример #2
0
bool Job::rollbackCopyBlocks(Report& report, CopyTarget& origTarget, CopySource& origSource)
{
	if (!origSource.overlaps(origTarget))
	{
		report.line() << i18nc("@info/plain", "Source and target for copying do not overlap: Rollback is not required.");
		return true;
	}

	try
	{
		CopySourceDevice& csd = dynamic_cast<CopySourceDevice&>(origSource);
		CopyTargetDevice& ctd = dynamic_cast<CopyTargetDevice&>(origTarget);

		// default: use values as if we were copying from front to back.
		qint64 undoSourceFirstSector = origTarget.firstSector();
		qint64 undoSourceLastSector = origTarget.firstSector() + origTarget.sectorsWritten() - 1;

		qint64 undoTargetFirstSector = origSource.firstSector();
		qint64 undoTargetLastSector = origSource.firstSector() + origTarget.sectorsWritten() - 1;

		if (origTarget.firstSector() > origSource.firstSector())
		{
			// we were copying from back to front
			undoSourceFirstSector = origTarget.firstSector() + origSource.length() - origTarget.sectorsWritten();
			undoSourceLastSector = origTarget.firstSector() + origSource.length() - 1;

			undoTargetFirstSector = origSource.lastSector() - origTarget.sectorsWritten() + 1;
			undoTargetLastSector = origSource.lastSector();
		}

		report.line() << i18nc("@info/plain", "Rollback from: First sector: %1, last sector: %2.", undoSourceFirstSector, undoSourceLastSector);
		report.line() << i18nc("@info/plain", "Rollback to: First sector: %1, last sector: %2.", undoTargetFirstSector, undoTargetLastSector);

		CopySourceDevice undoSource(ctd.device(), undoSourceFirstSector, undoSourceLastSector);
		if (!undoSource.open())
		{
			report.line() << i18nc("@info/plain", "Could not open device <filename>%1</filename> to rollback copying.", ctd.device().deviceNode());
			return false;
		}

		CopyTargetDevice undoTarget(csd.device(), undoTargetFirstSector, undoTargetLastSector);
		if (!undoTarget.open())
		{
			report.line() << i18nc("@info/plain", "Could not open device <filename>%1</filename> to rollback copying.", csd.device().deviceNode());
			return false;
		}

		return copyBlocks(report, undoTarget, undoSource);
	}
	catch ( ... )
	{
		report.line() << i18nc("@info/plain", "Rollback failed: Source or target are not devices.");
	}

	return false;
}
Пример #3
0
Calamares::JobResult
MoveFileSystemJob::exec()
{
    Report report( nullptr );
    QString partitionPath = partition()->partitionPath();
    CopySourceDevice moveSource( *m_device, m_oldFirstSector, m_oldFirstSector + m_length - 1 );
    CopyTargetDevice moveTarget( *m_device, m_newFirstSector, m_newFirstSector + m_length - 1 );

    if ( !moveSource.open() )
        return Calamares::JobResult::error(
                   QString(),
                   tr( "Could not open file system on partition %1 for moving." ).arg( partitionPath )
               );

    if ( !moveTarget.open() )
        return Calamares::JobResult::error(
                   QString(),
                   tr( "Could not create target for moving file system on partition %1." ).arg( partitionPath )
               );

    bool ok = copyBlocks( report, moveTarget, moveSource );
    if ( !ok )
    {
        if ( rollbackCopyBlocks( report, moveTarget, moveSource ) )
            return Calamares::JobResult::error(
                       QString(),
                       tr( "Moving of partition %1 failed, changes have been rolled back." ).arg( partitionPath )
                       + '\n' + report.toText()
                   );
        else
            return Calamares::JobResult::error(
                       QString(),
                       tr( "Moving of partition %1 failed. Roll back of the changes have failed." ).arg( partitionPath )
                       + '\n' + report.toText()
                   );
    }

    FileSystem& fs = partition()->fileSystem();
    fs.setFirstSector( m_newFirstSector );
    fs.setLastSector( m_newFirstSector + m_length - 1 );

    if ( !fs.updateBootSector( report, partitionPath ) )
        return Calamares::JobResult::error(
                   QString(),
                   tr( "Updating boot sector after the moving of partition %1 failed." ).arg( partitionPath )
                   + '\n' + report.toText()
               );

    return Calamares::JobResult::ok();
}
Пример #4
0
bool
MoveFileSystemJob::rollbackCopyBlocks( Report& report, CopyTargetDevice& origTarget, CopySourceDevice& origSource )
{
    if ( !origSource.overlaps( origTarget ) )
    {
        report.line() << tr( "Source and target for copying do not overlap: Rollback is not required." );
        return true;
    }

    // default: use values as if we were copying from front to back.
    qint64 undoSourceFirstSector = origTarget.firstSector();
    qint64 undoSourceLastSector = origTarget.firstSector() + origTarget.sectorsWritten() - 1;

    qint64 undoTargetFirstSector = origSource.firstSector();
    qint64 undoTargetLastSector = origSource.firstSector() + origTarget.sectorsWritten() - 1;

    if ( origTarget.firstSector() > origSource.firstSector() )
    {
        // we were copying from back to front
        undoSourceFirstSector = origTarget.firstSector() + origSource.length() - origTarget.sectorsWritten();
        undoSourceLastSector = origTarget.firstSector() + origSource.length() - 1;

        undoTargetFirstSector = origSource.lastSector() - origTarget.sectorsWritten() + 1;
        undoTargetLastSector = origSource.lastSector();
    }

    CopySourceDevice undoSource( origTarget.device(), undoSourceFirstSector, undoSourceLastSector );
    if ( !undoSource.open() )
    {
        report.line() << tr( "Could not open device %1 to rollback copying." )
                      .arg( origTarget.device().deviceNode() );
        return false;
    }

    CopyTargetDevice undoTarget( origSource.device(), undoTargetFirstSector, undoTargetLastSector );
    if ( !undoTarget.open() )
    {
        report.line() << tr( "Could not open device %1 to rollback copying." )
                      .arg( origSource.device().deviceNode() );
        return false;
    }

    return copyBlocks( report, undoTarget, undoSource );
}