begin moving all libparted-related stuff to a backend class.
svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1096873
This commit is contained in:
parent
f1ab5d8d7f
commit
05db0f55ea
|
@ -18,6 +18,7 @@
|
|||
############################################
|
||||
|
||||
file(GLOB partitionmanagerprivate_SRCS
|
||||
backend/*.cpp
|
||||
core/*.cpp
|
||||
util/*.cpp
|
||||
ops/*.cpp
|
||||
|
|
|
@ -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()
|
||||
{
|
|
@ -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;
|
||||
};
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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()
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(). */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue