bool RestoreOperation::execute(Report& parent)
{
	bool rval = false;
	bool warning = false;

	Report* report = parent.newChild(description());

	if (overwrittenPartition())
		restorePartition().setPartitionPath(overwrittenPartition()->devicePath());

	if (overwrittenPartition() || (rval = createPartitionJob()->run(*report)))
	{
		restorePartition().setState(Partition::StateNone);

		if ((rval = restoreJob()->run(*report)))
		{
			if ((rval = checkTargetJob()->run(*report)))
			{
				// If the partition was written over an existing one, the partition itself may now
				// be larger than the filesystem, so maximize the filesystem to the partition's size
				// or the image length, whichever is larger. If this fails, don't return an error, just
				// warn the user.
				if ((warning = !maximizeJob()->run(*report)))
					report->line() << xi18nc("@info/plain", "Warning: Maximizing file system on target partition <filename>%1</filename> to the size of the partition failed.", restorePartition().deviceNode());
			}
			else
				report->line() << xi18nc("@info/plain", "Checking target file system on partition <filename>%1</filename> after the restore failed.", restorePartition().deviceNode());
		}
		else
		{
			if (!overwrittenPartition())
				DeletePartitionJob(targetDevice(), restorePartition()).run(*report);

			report->line() << i18nc("@info/plain", "Restoring file system failed.");
		}
	}
	else
		report->line() << i18nc("@info/plain", "Creating the destination partition to restore to failed.");

	if (rval)
		setStatus(warning ? StatusFinishedWarning : StatusFinishedSuccess);
	else
		setStatus(StatusError);

	report->setStatus(i18nc("@info/plain status (success, error, warning...) of operation", "%1: %2", description(), statusText()));

	return rval;
}
Beispiel #2
0
/** Creates a new NewOperation.
    @param d the Device to create a new Partition on
    @param p pointer to the new Partition to create. May not be nullptr.
*/
NewOperation::NewOperation(Device& d, Partition* p) :
    Operation(),
    m_TargetDevice(d),
    m_NewPartition(p),
    m_CreatePartitionJob(new CreatePartitionJob(targetDevice(), newPartition())),
    m_CreateFileSystemJob(nullptr),
    m_SetPartFlagsJob(nullptr),
    m_SetFileSystemLabelJob(nullptr),
    m_CheckFileSystemJob(nullptr)
{
    addJob(createPartitionJob());

    const FileSystem& fs = newPartition().fileSystem();

    if (fs.type() != FileSystem::Extended) {
        // It would seem tempting to skip the CreateFileSystemJob or the
        // SetFileSystemLabelJob if either has nothing to do (unformatted FS or
        // empty label). However, the user might later on decide to change FS or
        // label. The operation stack will merge these operations with this one here
        // and if the jobs don't exist things will break.

        m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition());
        addJob(createFileSystemJob());

        if (fs.type() == FileSystem::Lvm2_PV) {
            m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::FlagLvm);
            addJob(setPartFlagsJob());
        }

        m_SetFileSystemLabelJob = new SetFileSystemLabelJob(newPartition(), fs.label());
        addJob(setLabelJob());

        m_CheckFileSystemJob = new CheckFileSystemJob(newPartition());
        addJob(checkJob());
    }
}