begin moving all libparted-related stuff to a backend class.

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1096873
This commit is contained in:
Volker Lanz 2010-02-27 21:32:00 +00:00
parent f1ab5d8d7f
commit 05db0f55ea
19 changed files with 617 additions and 123 deletions

View File

@ -18,6 +18,7 @@
############################################
file(GLOB partitionmanagerprivate_SRCS
backend/*.cpp
core/*.cpp
util/*.cpp
ops/*.cpp

View File

@ -17,8 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "core/corebackend.h"
#include "core/libpartedbackend.h"
#include "backend/corebackend.h"
#include "backend/libpartedbackend.h"
CoreBackend* CoreBackend::self()
{

View File

@ -17,12 +17,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(BACKEND__H)
#if !defined(COREBACKEND__H)
#define BACKEND__H
#define COREBACKEND__H
#include "util/libpartitionmanagerexport.h"
class CoreBackendDevice;
class Device;
class QString;
@ -37,6 +38,9 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT CoreBackend
public:
static CoreBackend* self();
virtual CoreBackendDevice* openDevice(const QString& device_node) = 0;
virtual bool closeDevice(CoreBackendDevice* core_device) = 0;
public:
virtual Device* scanDevice(const QString& device_node) = 0;
};

View File

@ -0,0 +1,25 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "backend/corebackenddevice.h"
CoreBackendDevice::CoreBackendDevice(const QString& device_node) :
m_DeviceNode(device_node)
{
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(COREBACKENDDEVICE__H)
#define COREBACKENDDEVICE__H
#include <QString>
#include <qglobal.h>
class CoreBackendPartition;
class Partition;
class Report;
class CoreBackendDevice
{
public:
CoreBackendDevice(const QString& device_node);
virtual ~CoreBackendDevice() {}
public:
virtual const QString& deviceNode() const { return m_DeviceNode; }
virtual bool open() = 0;
virtual bool close() = 0;
virtual bool commit(quint32 timeout = 10) = 0;
virtual CoreBackendPartition* getExtendedPartition() = 0;
virtual CoreBackendPartition* getPartitionBySector(qint64 sector) = 0;
virtual bool createPartition(Report& report, Partition& partition) = 0;
private:
const QString m_DeviceNode;
};
#endif

View File

@ -0,0 +1,25 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "backend/corebackendpartition.h"
CoreBackendPartition::CoreBackendPartition()
{
}

View File

@ -0,0 +1,38 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(COREBACKENDPARTITION__H)
#define COREBACKENDPARTITION__H
#include "core/partitiontable.h"
class Report;
class CoreBackendPartition
{
public:
CoreBackendPartition();
virtual ~CoreBackendPartition() {}
public:
virtual bool setFlag(Report& report, PartitionTable::Flag flag, bool state) = 0;
};
#endif

View File

@ -20,7 +20,9 @@
/** @file
*/
#include "core/libpartedbackend.h"
#include "backend/libpartedbackend.h"
#include "backend/libparteddevice.h"
#include "core/device.h"
#include "core/partition.h"
#include "core/partitiontable.h"
@ -226,7 +228,8 @@ static PartitionTable::Flags availableFlags(PedPartition* p)
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
if (ped_partition_is_flag_available(p, flagmap[i].pedFlag))
{
// workaround:: see above
// Workaround: libparted claims the hidden flag is available for extended partitions, but
// throws an error when we try to set or clear it. So skip this combination. Also see setFlag.
if (p->type != PED_PARTITION_EXTENDED || flagmap[i].flag != PartitionTable::FlagHidden)
flags |= flagmap[i].flag;
}
@ -338,6 +341,11 @@ const LibPartedBackend::FlagMap* LibPartedBackend::flagMap()
return flagmap;
}
quint32 LibPartedBackend::flagMapSize()
{
return sizeof(flagmap) / sizeof(flagmap[0]);
}
/** Create a Device for the given device_node and scan it for partitions.
@param device_node the device node (e.g. "/dev/sda")
@return the created Device object. callers need to free this.
@ -369,3 +377,22 @@ Device* LibPartedBackend::scanDevice(const QString& device_node)
return d;
}
CoreBackendDevice* LibPartedBackend::openDevice(const QString& device_node)
{
LibPartedDevice* device = new LibPartedDevice(device_node);
if (!device->open())
{
delete device;
device = NULL;
}
return device;
}
bool LibPartedBackend::closeDevice(CoreBackendDevice* core_device)
{
delete core_device;
return true;
}

View File

@ -21,8 +21,9 @@
#define LIBPARTED__H
#include "backend/corebackend.h"
#include "core/partitiontable.h"
#include "core/corebackend.h"
#include <parted/parted.h>
@ -56,6 +57,10 @@ class LibPartedBackend : public CoreBackend
public:
static const FlagMap* flagMap();
static quint32 flagMapSize();
virtual CoreBackendDevice* openDevice(const QString& device_node);
virtual bool closeDevice(CoreBackendDevice* core_device);
Device* scanDevice(const QString& device_node);
};

View File

@ -0,0 +1,212 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "backend/libparteddevice.h"
#include "backend/libpartedpartition.h"
#include "core/partition.h"
#include "fs/filesystem.h"
#include "util/externalcommand.h"
#include "util/globallog.h"
#include "util/report.h"
#include <klocale.h>
#include <kdebug.h>
#include <unistd.h>
LibPartedDevice::LibPartedDevice(const QString& device_node) :
CoreBackendDevice(device_node)
{
}
LibPartedDevice::~LibPartedDevice()
{
close();
}
bool LibPartedDevice::open()
{
m_PedDevice = ped_device_get(deviceNode().toAscii());
m_PedDisk = m_PedDevice ? ped_disk_new(m_PedDevice) : NULL;
return pedDevice() != NULL && pedDisk() != NULL;
}
bool LibPartedDevice::close()
{
if (pedDisk())
ped_disk_destroy(pedDisk());
m_PedDisk = NULL;
m_PedDevice = NULL;
return true;
}
bool LibPartedDevice::commit(quint32 timeout)
{
if (pedDisk() == NULL)
return false;
bool rval = ped_disk_commit_to_dev(pedDisk());
// The GParted authors have found a bug in libparted that causes it to intermittently
// not commit changes to the Linux kernel, probably a race. Until this is fixed in
// libparted, the following patch should help alleviate the consequences by just re-trying
// committing to the OS if it fails the first time after a short pause.
// See: http://git.gnome.org/browse/gparted/commit/?id=bf86fd3f9ceb0096dfe87a8c9a38403c13b13f00
if (rval)
{
rval = ped_disk_commit_to_os(pedDisk());
if (!rval)
{
sleep(1);
rval = ped_disk_commit_to_os(pedDisk());
}
}
if (!ExternalCommand("udevadm", QStringList() << "settle" << "--timeout=" + QString::number(timeout)).run() &&
!ExternalCommand("udevsettle", QStringList() << "--timeout=" + QString::number(timeout)).run())
sleep(timeout);
return rval;
}
CoreBackendPartition* LibPartedDevice::getExtendedPartition()
{
PedPartition* pedPartition = ped_disk_extended_partition(pedDisk());
if (pedPartition == NULL)
return NULL;
return new LibPartedPartition(pedPartition);
}
CoreBackendPartition* LibPartedDevice::getPartitionBySector(qint64 sector)
{
PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), sector);
if (pedPartition == NULL)
return NULL;
return new LibPartedPartition(pedPartition);
}
static const struct
{
FileSystem::Type type;
QString name;
} mapFileSystemTypeToLibPartedName[] =
{
{ FileSystem::Ext2, "ext2" },
{ FileSystem::Ext3, "ext3" },
{ FileSystem::Ext4, "ext4" },
{ FileSystem::LinuxSwap, "linux-swap" },
{ FileSystem::Fat16, "fat16" },
{ FileSystem::Fat32, "fat32" },
{ FileSystem::Ntfs, "ntfs" },
{ FileSystem::ReiserFS, "reiserfs" },
{ FileSystem::Reiser4, "reiser4" },
{ FileSystem::Xfs, "xfs" },
{ FileSystem::Jfs, "jfs" },
{ FileSystem::Hfs, "hfs" },
{ FileSystem::HfsPlus, "hfs+" },
{ FileSystem::Ufs, "ufs" }
};
static PedFileSystemType* getPedFileSystemType(FileSystem::Type t)
{
for (quint32 i = 0; i < sizeof(mapFileSystemTypeToLibPartedName) / sizeof(mapFileSystemTypeToLibPartedName[0]); i++)
if (mapFileSystemTypeToLibPartedName[i].type == t)
return ped_file_system_type_get(mapFileSystemTypeToLibPartedName[i].name.toAscii());
// if we didn't find anything, go with ext2 as a safe fallback
return ped_file_system_type_get("ext2");
}
bool LibPartedDevice::createPartition(Report& report, Partition& partition)
{
Q_ASSERT(pedDevice());
Q_ASSERT(pedDevice()->path);
Q_ASSERT(partition.devicePath() == pedDevice()->path);
bool rval = false;
// According to libParted docs, PedPartitionType can be "NULL if unknown". That's obviously wrong,
// it's a typedef for an enum. So let's use something the libparted devs will hopefully never
// use...
PedPartitionType pedType = static_cast<PedPartitionType>(0xffffffff);
if (partition.roles().has(PartitionRole::Extended))
pedType = PED_PARTITION_EXTENDED;
else if (partition.roles().has(PartitionRole::Logical))
pedType = PED_PARTITION_LOGICAL;
else if (partition.roles().has(PartitionRole::Primary))
pedType = PED_PARTITION_NORMAL;
if (pedType == static_cast<int>(0xffffffff))
{
report.line() << i18nc("@info/plain", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition.deviceNode(), partition.roles().toString());
return false;
}
PedFileSystemType* pedFsType = (partition.roles().has(PartitionRole::Extended) || partition.fileSystem().type() == FileSystem::Unformatted) ? NULL : getPedFileSystemType(partition.fileSystem().type());
PedPartition* pedPartition = ped_partition_new(pedDisk(), pedType, pedFsType, partition.firstSector(), partition.lastSector());
if (pedPartition == NULL)
{
report.line() << i18nc("@info/plain", "Failed to create new partition <filename>%1</filename>.", partition.deviceNode());
return false;
}
PedConstraint* pedConstraint = NULL;
PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), partition.firstSector(), partition.length());
if (pedGeometry)
pedConstraint = ped_constraint_exact(pedGeometry);
if (pedConstraint == NULL)
{
report.line() << i18nc("@info/plain", "Failed to create a new partition: could not get geometry for constraint.");
return false;
}
if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint))
{
partition.setNumber(pedPartition->num);
partition.setState(Partition::StateNone);
partition.setFirstSector(pedPartition->geom.start);
partition.setLastSector(pedPartition->geom.end);
rval = true;
}
else
report.line() << i18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition.deviceNode(), pedDisk()->dev->path);
ped_constraint_destroy(pedConstraint);
return rval;
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(LIBPARTEDDEVICE__H)
#define LIBPARTEDDEVICE__H
#include "backend/corebackenddevice.h"
#include <qglobal.h>
#include <parted/parted.h>
class Partition;
class Report;
class LibPartedDevice : public CoreBackendDevice
{
Q_DISABLE_COPY(LibPartedDevice);
public:
LibPartedDevice(const QString& device_node);
~LibPartedDevice();
public:
virtual bool open();
virtual bool close();
virtual bool commit(quint32 timeout = 10);
virtual CoreBackendPartition* getExtendedPartition();
virtual CoreBackendPartition* getPartitionBySector(qint64 sector);
virtual bool createPartition(Report& report, Partition& partition);
protected:
PedDevice* pedDevice() { return m_PedDevice; }
PedDisk* pedDisk() { return m_PedDisk; }
private:
PedDevice* m_PedDevice;
PedDisk* m_PedDisk;
};
#endif

View File

@ -0,0 +1,64 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "backend/libpartedpartition.h"
#include "backend/libpartedbackend.h"
#include "util/report.h"
#include <klocale.h>
LibPartedPartition::LibPartedPartition(PedPartition* ped_partition) :
CoreBackendPartition(),
m_PedPartition(ped_partition)
{
}
static PedPartitionFlag getPedFlag(PartitionTable::Flag flag)
{
for (quint32 i = 0; i < LibPartedBackend::flagMapSize(); i++)
if (LibPartedBackend::flagMap()[i].flag == flag)
return LibPartedBackend::flagMap()[i].pedFlag;
return static_cast<PedPartitionFlag>(-1);
}
bool LibPartedPartition::setFlag(Report& report, PartitionTable::Flag partitionManagerFlag, bool state)
{
Q_ASSERT(pedPartition() != NULL);
const PedPartitionFlag f = getPedFlag(partitionManagerFlag);
// ignore flags that don't exist for this partition
if (!ped_partition_is_flag_available(pedPartition(), f))
{
report.line() << i18nc("@info/plain", "The flag \"%1\" is not available on the partition's partition table.", PartitionTable::flagName(partitionManagerFlag));
return true;
}
// Workaround: libparted claims the hidden flag is available for extended partitions, but
// throws an error when we try to set or clear it. So skip this combination.
if (pedPartition()->type == PED_PARTITION_EXTENDED && partitionManagerFlag == PartitionTable::FlagHidden)
return true;
if (!ped_partition_set_flag(pedPartition(), f, state ? 1 : 0))
return false;
return true;
}

View File

@ -0,0 +1,50 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(LIBPARTEDPARTITION__H)
#define LIBPARTEDPARTITION__H
#include "backend/corebackendpartition.h"
#include "core/partitiontable.h"
#include <parted/parted.h>
class Report;
class LibPartedPartition : public CoreBackendPartition
{
Q_DISABLE_COPY(LibPartedPartition);
public:
LibPartedPartition(PedPartition* ped_partition);
public:
virtual bool setFlag(Report& report, PartitionTable::Flag flag, bool state);
private:
PedPartition* pedPartition() { return m_PedPartition; }
private:
PedPartition* m_PedPartition;
};
#endif

View File

@ -17,8 +17,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "backend/corebackend.h"
#include "core/devicescanner.h"
#include "core/corebackend.h"
#include "core/operationstack.h"
#include "core/device.h"

View File

@ -30,6 +30,7 @@
class Device;
class OperationStack;
class LibPartedDevice;
class PartResizerWidget;
class InsertDialog;
@ -71,6 +72,7 @@ class Partition : public PartitionNode
friend class OperationStack;
friend class Device;
friend class PartitionNode;
friend class LibPartedDevice;
friend class PartResizerWidget;
friend class InsertDialog;

View File

@ -19,6 +19,9 @@
#include "jobs/createpartitionjob.h"
#include "backend/corebackend.h"
#include "backend/corebackenddevice.h"
#include "core/partition.h"
#include "core/device.h"
@ -47,66 +50,25 @@ bool CreatePartitionJob::run(Report& parent)
Report* report = jobStarted(parent);
// According to libParted docs, PedPartitionType can be "NULL if unknown". That's obviously wrong,
// it's a typedef for an enum. So let's use something the libparted devs will hopefully never
// use...
PedPartitionType pedType = static_cast<PedPartitionType>(0xffffffff);
CoreBackendDevice* backendDevice = CoreBackend::self()->openDevice(device().deviceNode());
if (partition().roles().has(PartitionRole::Extended))
pedType = PED_PARTITION_EXTENDED;
else if (partition().roles().has(PartitionRole::Logical))
pedType = PED_PARTITION_LOGICAL;
else if (partition().roles().has(PartitionRole::Primary))
pedType = PED_PARTITION_NORMAL;
if (pedType == static_cast<int>(0xffffffff))
if (backendDevice)
{
report->line() << i18nc("@info/plain", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition().deviceNode(), partition().roles().toString());
}
else if (openPed(device().deviceNode()))
{
PedFileSystemType* pedFsType = (partition().roles().has(PartitionRole::Extended) || partition().fileSystem().type() == FileSystem::Unformatted) ? NULL : getPedFileSystemType(partition().fileSystem().type());
PedPartition* pedPartition = ped_partition_new(pedDisk(), pedType, pedFsType, partition().firstSector(), partition().lastSector());
if (pedPartition)
{
PedConstraint* pedConstraint = NULL;
PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), partition().firstSector(), partition().length());
if (pedGeometry)
pedConstraint = ped_constraint_exact(pedGeometry);
if (pedConstraint)
{
if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint) && commit())
{
partition().setNumber(pedPartition->num);
partition().setState(Partition::StateNone);
partition().setFirstSector(pedPartition->geom.start);
partition().setLastSector(pedPartition->geom.end);
rval = true;
}
else
report->line() << i18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());
ped_constraint_destroy(pedConstraint);
}
else
report->line() << i18nc("@info/plain", "Failed to create a new partition: could not get geometry for constraint.");
}
if (!backendDevice->createPartition(*report, partition()))
report->line() << i18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());
else
report->line() << i18nc("@info/plain", "Failed to create new partition <filename>%1</filename>.", partition().deviceNode());
closePed();
{
backendDevice->commit();
rval = true;
}
delete backendDevice;
}
else
report->line() << i18nc("@info/plain", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
jobFinished(*report, rval);
return rval;
}

View File

@ -38,28 +38,6 @@
#include <unistd.h>
#include <blkid/blkid.h>
static const struct
{
FileSystem::Type type;
QString name;
} mapFileSystemTypeToLibPartedName[] =
{
{ FileSystem::Ext2, "ext2" },
{ FileSystem::Ext3, "ext3" },
{ FileSystem::Ext4, "ext4" },
{ FileSystem::LinuxSwap, "linux-swap" },
{ FileSystem::Fat16, "fat16" },
{ FileSystem::Fat32, "fat32" },
{ FileSystem::Ntfs, "ntfs" },
{ FileSystem::ReiserFS, "reiserfs" },
{ FileSystem::Reiser4, "reiser4" },
{ FileSystem::Xfs, "xfs" },
{ FileSystem::Jfs, "jfs" },
{ FileSystem::Hfs, "hfs" },
{ FileSystem::HfsPlus, "hfs+" },
{ FileSystem::Ufs, "ufs" }
};
Job::Job() :
m_PedDevice(NULL),
m_PedDisk(NULL),
@ -124,16 +102,6 @@ bool Job::commit(PedDisk* disk, quint32 timeout)
return rval;
}
PedFileSystemType* Job::getPedFileSystemType(FileSystem::Type t)
{
for (quint32 i = 0; i < sizeof(mapFileSystemTypeToLibPartedName) / sizeof(mapFileSystemTypeToLibPartedName[0]); i++)
if (mapFileSystemTypeToLibPartedName[i].type == t)
return ped_file_system_type_get(mapFileSystemTypeToLibPartedName[i].name.toAscii());
// if we didn't find anything, go with ext2 as a safe fallback
return ped_file_system_type_get("ext2");
}
bool Job::copyBlocks(Report& report, CopyTarget& target, CopySource& source)
{
/** @todo copyBlocks() assumes that source.sectorSize() == target.sectorSize(). */

View File

@ -68,7 +68,7 @@ class Job : public QObject
void started();
void progress(int);
void finished();
public:
virtual qint32 numSteps() const { return 1; } /**< @return the number of steps the job takes to complete */
virtual QString description() const = 0; /**< @return the Job's description */
@ -78,13 +78,13 @@ class Job : public QObject
virtual QString statusText() const;
JobStatus status() const { return m_Status; } /**< @return the Job's current status */
static FileSystem::Type detectFileSystem(PedDevice* pedDevice, PedPartition* pedPartition);
protected:
bool openPed(const QString& path, bool diskFailOk = false);
void closePed();
bool commit(quint32 timeout = 10);
static bool commit(PedDisk* disk, quint32 timeout = 10);
@ -103,7 +103,6 @@ class Job : public QObject
PedDevice* pedDevice() { return m_PedDevice; }
PedDisk* pedDisk() { return m_PedDisk; }
static PedFileSystemType* getPedFileSystemType(FileSystem::Type t);
static void pedTimerHandler(PedTimer* pedTimer, void* ctx);
private:

View File

@ -19,11 +19,14 @@
#include "jobs/setpartflagsjob.h"
#include "backend/corebackend.h"
#include "backend/corebackenddevice.h"
#include "backend/corebackendpartition.h"
#include "core/device.h"
#include "core/partition.h"
#include "core/partitionrole.h"
#include "core/partitiontable.h"
#include "core/libpartedbackend.h"
#include "util/report.h"
@ -44,7 +47,7 @@ SetPartFlagsJob::SetPartFlagsJob(Device& d, Partition& p, PartitionTable::Flags
qint32 SetPartFlagsJob::numSteps() const
{
return sizeof(LibPartedBackend::flagMap()) / sizeof(LibPartedBackend::flagMap()[0]);
return PartitionTable::flagList().size();
}
bool SetPartFlagsJob::run(Report& parent)
@ -53,45 +56,39 @@ bool SetPartFlagsJob::run(Report& parent)
Report* report = jobStarted(parent);
if (openPed(device().deviceNode()))
CoreBackendDevice* backendDevice = CoreBackend::self()->openDevice(device().deviceNode());
if (backendDevice != NULL && backendDevice->open())
{
PedPartition* pedPartition = (partition().roles().has(PartitionRole::Extended)) ? ped_disk_extended_partition(pedDisk()) : ped_disk_get_partition_by_sector(pedDisk(), partition().firstSector());
CoreBackendPartition* backendPartition = (partition().roles().has(PartitionRole::Extended)) ? backendDevice->getExtendedPartition() : backendDevice->getPartitionBySector(partition().firstSector());
if (pedPartition)
if (backendPartition)
{
for (quint32 i = 0; i < sizeof(LibPartedBackend::flagMap()) / sizeof(LibPartedBackend::flagMap()[0]); i++)
quint32 count = 0;
foreach(PartitionTable::Flag f, PartitionTable::flagList())
{
emit progress(i + 1);
emit progress(++count);
if (!ped_partition_is_flag_available(pedPartition, LibPartedBackend::flagMap()[i].pedFlag))
const bool state = (flags() & f) ? true : false;
if (!backendPartition->setFlag(*report, f, state))
{
report->line() << i18nc("@info/plain", "The flag \"%1\" is not available on the partition's partition table.", PartitionTable::flagName(LibPartedBackend::flagMap()[i].flag));
continue;
}
// Workaround: libparted claims the hidden flag is available for extended partitions, but
// throws an error when we try to set or clear it. So skip this combination (also see below in
// availableFlags()).
if (pedPartition->type == PED_PARTITION_EXTENDED && LibPartedBackend::flagMap()[i].flag == PartitionTable::FlagHidden)
continue;
int state = (flags() & LibPartedBackend::flagMap()[i].flag) ? 1 : 0;
if (!ped_partition_set_flag(pedPartition, LibPartedBackend::flagMap()[i].pedFlag, state))
{
report->line() << i18nc("@info/plain", "There was an error setting flag %1 for partition <filename>%2</filename> to state %3.", PartitionTable::flagName(LibPartedBackend::flagMap()[i].flag), partition().deviceNode(), state ? i18nc("@info flag turned on, active", "on") : i18nc("@info flag turned off, inactive", "off"));
report->line() << i18nc("@info/plain", "There was an error setting flag %1 for partition <filename>%2</filename> to state %3.", PartitionTable::flagName(f), partition().deviceNode(), state ? i18nc("@info/plain flag turned on, active", "on") : i18nc("@info/plain flag turned off, inactive", "off"));
rval = false;
}
}
if (!commit())
if (!backendDevice->commit())
rval = false;
delete backendPartition;
}
else
report->line() << i18nc("@info/plain", "Could not find partition <filename>%1</filename> on device <filename>%2</filename> to set partition flags.", partition().deviceNode(), device().deviceNode());
closePed();
delete backendDevice;
}
else
report->line() << i18nc("@info/plain", "Could not open device <filename>%1</filename> to set partition flags for partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());