Fix detection of partitions' paths.

Previously, partition number was added to device path.
However, there are devices with more complicated numbering scheme,
e.g. memory cards may have /dev/mmcblk0p1.
It seems that the easiest way to handle this is to use partition
path instead of device path + partition number .
BUG:256964

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1337488
This commit is contained in:
Andrius Štikonas 2013-02-05 00:09:43 +00:00
parent d6c685a2a9
commit 59e5a656c5
15 changed files with 53 additions and 36 deletions

View File

@ -106,7 +106,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT CoreBackendPartitionTable
* @param partition the new partition to create on disk
* @return the new number the OS sees the partition under (e.g. 7 for "/dev/sda7") or -1 on failure
*/
virtual qint32 createPartition(Report& report, const Partition& partition) = 0;
virtual QString createPartition(Report& report, const Partition& partition) = 0;
/**
* Update the geometry for a partition in the partition table.

View File

@ -41,16 +41,15 @@
@param fs pointer to the Partition's FileSystem object. The Partition object will take ownership of this.
@param sectorStart the first sector of the Partition on its Device
@param sectorEnd the last sector of the Partition on its Device
@param number the Partition's device number, e.g. 7 for /dev/sdd7
@param partitionPath the Partition's path, e.g. /dev/sda4 or /dev/mmcblk0p1
@param availableFlags the flags available for this Partition
@param mountPoint mount point for this Partition
@param mounted true if the Partition is mounted
@param activeFlags active flags for this Partition
@param state the Partition's state
*/
Partition::Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, qint32 number, PartitionTable::Flags availableFlags, const QString& mountPoint, bool mounted, PartitionTable::Flags activeFlags, State state) :
Partition::Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags, const QString& mountPoint, bool mounted, PartitionTable::Flags activeFlags, State state) :
PartitionNode(),
m_Number(number),
m_Children(),
m_Parent(parent),
m_FileSystem(fs),
@ -65,6 +64,7 @@ Partition::Partition(PartitionNode* parent, const Device& device, const Partitio
m_SectorSize(device.logicalSectorSize()),
m_State(state)
{
setPartitionPath(partitionPath);
Q_ASSERT(m_Parent);
}
@ -89,7 +89,6 @@ Partition::~Partition()
*/
Partition::Partition(const Partition& other) :
PartitionNode(),
m_Number(other.m_Number),
m_Children(),
m_Parent(other.m_Parent),
m_FileSystem(FileSystemFactory::create(other.fileSystem())),
@ -104,6 +103,7 @@ Partition::Partition(const Partition& other) :
m_SectorSize(other.m_SectorSize),
m_State(other.m_State)
{
setPartitionPath(other.m_PartitionPath);
foreach(const Partition* child, other.children())
{
Partition* p = new Partition(*child);
@ -133,6 +133,7 @@ Partition& Partition::operator=(const Partition& other)
m_FirstSector = other.m_FirstSector;
m_LastSector = other.m_LastSector;
m_DevicePath = other.m_DevicePath;
m_PartitionPath = other.m_PartitionPath;
m_MountPoint = other.m_MountPoint;
m_AvailableFlags = other.m_AvailableFlags;
m_ActiveFlags = other.m_ActiveFlags;
@ -165,12 +166,10 @@ QString Partition::deviceNode() const
if (state() == StateRestore)
return i18nc("@item partition name", "Restored Partition");
QString res = m_DevicePath + QString::number(number());
if (state() == StateCopy)
return i18nc("@item partition name", "Copy of %1", res);
return i18nc("@item partition name", "Copy of %1", partitionPath());
return res;
return partitionPath();
}
/** @return the sectors used in the Partition's FileSystem or, in case of an extended partition, the sum of used sectors of the Partition's children */
@ -216,10 +215,12 @@ void Partition::adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber
foreach (Partition* p, children())
{
QString path = p->partitionPath();
path.remove(QRegExp("([0-9]+$)"));
if (deletedNumber > 4 && p->number() > deletedNumber)
p->setNumber(p->number() - 1);
p->setPartitionPath(path + QString::number(p->number() - 1));
else if (insertedNumber > 4 && p->number() >= insertedNumber)
p->setNumber(p->number() + 1);
p->setPartitionPath(path + QString::number(p->number() + 1));
}
}
@ -352,6 +353,18 @@ void Partition::deleteFileSystem()
m_FileSystem = NULL;
}
void Partition::setPartitionPath(const QString& s)
{
m_PartitionPath = s;
QRegExp rxPartitionNumber("([0-9]+$)");
if (rxPartitionNumber.indexIn(partitionPath()) > -1)
{
setNumber(rxPartitionNumber.cap().toInt());
return;
}
setNumber(-1);
}
void Partition::setFileSystem(FileSystem* fs)
{
m_FileSystem = fs;

View File

@ -114,7 +114,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
};
public:
Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, qint32 number, PartitionTable::Flags availableFlags = PartitionTable::FlagNone, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::FlagNone, State state = StateNone);
Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::FlagNone, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::FlagNone, State state = StateNone);
~Partition();
public:
@ -136,6 +136,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
const Partitions& children() const { return m_Children; } /**< @return the Partition's children. empty for non-extended. */
const QString& devicePath() const { return m_DevicePath; } /**< @return the Partition's device path, e.g. /dev/sdd */
const QString& partitionPath() const { return m_PartitionPath; } /**< @return the Partition's path, e.g. /dev/sdd1 */
qint64 firstSector() const { return m_FirstSector; } /**< @return the Partition's first sector on the Device */
qint64 lastSector() const { return m_LastSector; } /**< @return the Partition's last sector on the Device */
@ -179,6 +180,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
protected:
void append(Partition* p) { m_Children.append(p); }
void setDevicePath(const QString& s) { m_DevicePath = s; }
void setPartitionPath(const QString& s);
void setRoles(const PartitionRole& r) { m_Roles = r; }
void setMountPoint(const QString& s) { m_MountPoint = s; }
void setFlags(PartitionTable::Flags f) { m_ActiveFlags = f; }
@ -191,11 +193,12 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
void unsetFlag(PartitionTable::Flag f) { m_ActiveFlags &= ~f; }
void setParent(PartitionNode* p) { m_Parent = p; }
void setFileSystem(FileSystem* fs);
void setNumber(qint32 n) { m_Number = n; }
void setState(State s) { m_State = s; }
void deleteFileSystem();
private:
void setNumber(qint32 n) { m_Number = n; }
qint32 m_Number;
Partitions m_Children;
PartitionNode* m_Parent;
@ -204,6 +207,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
qint64 m_FirstSector;
qint64 m_LastSector;
QString m_DevicePath;
QString m_PartitionPath;
QString m_MountPoint;
PartitionTable::Flags m_AvailableFlags;
PartitionTable::Flags m_ActiveFlags;

View File

@ -257,7 +257,7 @@ Partition* createUnallocated(const Device& device, PartitionNode& parent, qint64
if (!PartitionTable::getUnallocatedRange(device, parent, start, end))
return NULL;
return new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end), start, end, -1);
return new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end), start, end, "");
}
/** Removes all unallocated children from a PartitionNode

View File

@ -116,7 +116,7 @@ void InfoPane::showPartition(Qt::DockWidgetArea area, const Partition& p)
int y = createHeader(p.deviceNode(), cols(area));
if (p.fileSystem().type() == FileSystem::Luks)
{
QString deviceNode = p.devicePath() + QString::number(p.number());
QString deviceNode = p.partitionPath();
createLabels(i18nc("@label partition", "File system:"), p.fileSystem().name(), cols(area), x, y);
createLabels(i18nc("@label partition", "Capacity:"), Capacity::formatByteSize(p.capacity()), cols(area), x, y);
createLabels(i18nc("@label partition", "Cipher name:"), FS::luks::getCipherName(deviceNode), cols(area), x, y);

View File

@ -891,7 +891,7 @@ void MainWindow::onImportPartitionTable()
if (fs->supportSetLabel() != FileSystem::cmdSupportNone && !volumeLabel.isEmpty())
fs->setLabel(volumeLabel);
Partition* p = new Partition(parent, device, role, fs, firstSector, lastSector, -1, PartitionTable::FlagNone, QString(), false, PartitionTable::FlagNone, Partition::StateNew);
Partition* p = new Partition(parent, device, role, fs, firstSector, lastSector, "", PartitionTable::FlagNone, QString(), false, PartitionTable::FlagNone, Partition::StateNew);
operationStack().push(new NewOperation(device, p));
}

View File

@ -58,12 +58,12 @@ bool CreatePartitionJob::run(Report& parent)
if (backendPartitionTable)
{
qint32 num = backendPartitionTable->createPartition(*report, partition());
QString partitionPath = backendPartitionTable->createPartition(*report, partition());
if (num > 0)
if (partitionPath != "")
{
rval = true;
partition().setNumber(num);
partition().setPartitionPath(partitionPath);
partition().setState(Partition::StateNone);
backendPartitionTable->commit();
}

View File

@ -147,7 +147,7 @@ bool CopyOperation::execute(Report& parent)
if (overwrittenPartition())
{
copiedPartition().setDevicePath(overwrittenPartition()->devicePath());
copiedPartition().setNumber(overwrittenPartition()->number());
copiedPartition().setPartitionPath(overwrittenPartition()->devicePath());
}
// now run the copy job itself
@ -273,8 +273,8 @@ Partition* CopyOperation::createCopy(const Partition& target, const Partition& s
{
Partition* p = target.roles().has(PartitionRole::Unallocated) ? new Partition(source) : new Partition(target);
p->setNumber(source.number());
p->setDevicePath(source.devicePath());
p->setPartitionPath(source.partitionPath());
p->setState(Partition::StateCopy);
p->deleteFileSystem();

View File

@ -129,7 +129,7 @@ Partition* NewOperation::createNew(const Partition& cloneFrom)
p->deleteFileSystem();
p->setFileSystem(FileSystemFactory::create(FileSystem::defaultFileSystem(), p->firstSector(), p->lastSector()));
p->setState(Partition::StateNew);
p->setNumber(-1);
p->setPartitionPath("");
return p;
}

View File

@ -126,7 +126,7 @@ bool RestoreOperation::execute(Report& parent)
Report* report = parent.newChild(description());
if (overwrittenPartition())
restorePartition().setNumber(overwrittenPartition()->number());
restorePartition().setPartitionPath(overwrittenPartition()->devicePath());
if (overwrittenPartition() || (rval = createPartitionJob()->run(*report)))
{
@ -229,7 +229,7 @@ Partition* RestoreOperation::createRestorePartition(const Device& device, Partit
return NULL;
const qint64 end = start + fileInfo.size() / device.logicalSectorSize() - 1;
Partition* p = new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end), start, end, -1);
Partition* p = new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end), start, end, "");
p->setState(Partition::StateRestore);
return p;

View File

@ -67,12 +67,12 @@ CoreBackendPartition* DummyPartitionTable::getPartitionBySector(qint64 sector)
return new DummyPartition();
}
qint32 DummyPartitionTable::createPartition(Report& report, const Partition& partition)
QString DummyPartitionTable::createPartition(Report& report, const Partition& partition)
{
Q_UNUSED(report);
Q_UNUSED(partition);
return true;
return "dummy";
}
bool DummyPartitionTable::deletePartition(Report& report, const Partition& partition)

View File

@ -45,7 +45,7 @@ class DummyPartitionTable : public CoreBackendPartitionTable
virtual CoreBackendPartition* getExtendedPartition();
virtual CoreBackendPartition* getPartitionBySector(qint64 sector);
virtual qint32 createPartition(Report& report, const Partition& partition);
virtual QString createPartition(Report& report, const Partition& partition);
virtual bool deletePartition(Report& report, const Partition& partition);
virtual bool updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end);
virtual bool clobberFileSystem(Report& report, const Partition& partition);

View File

@ -367,7 +367,7 @@ void LibPartedBackend::scanDevicePartitions(PedDevice*, Device& d, PedDisk* pedD
if (parent == NULL)
parent = d.partitionTable();
const QString node = pedDisk->dev->path + QString::number(pedPartition->num);
const QString node = QString(ped_partition_get_path(pedPartition));
FileSystem* fs = FileSystemFactory::create(type, pedPartition->geom.start, pedPartition->geom.end);
// libparted does not handle LUKS partitions
@ -384,7 +384,7 @@ void LibPartedBackend::scanDevicePartitions(PedDevice*, Device& d, PedDisk* pedD
mounted = ped_partition_is_busy(pedPartition);
}
Partition* part = new Partition(parent, d, PartitionRole(r), fs, pedPartition->geom.start, pedPartition->geom.end, pedPartition->num, availableFlags(pedPartition), mountPoint, mounted, activeFlags(pedPartition));
Partition* part = new Partition(parent, d, PartitionRole(r), fs, pedPartition->geom.start, pedPartition->geom.end, node, availableFlags(pedPartition), mountPoint, mounted, activeFlags(pedPartition));
readSectorsUsed(pedDisk, d, *part, mountPoint);

View File

@ -144,11 +144,11 @@ static PedFileSystemType* getPedFileSystemType(FileSystem::Type t)
return ped_file_system_type_get("ext2");
}
qint32 LibPartedPartitionTable::createPartition(Report& report, const Partition& partition)
QString LibPartedPartitionTable::createPartition(Report& report, const Partition& partition)
{
Q_ASSERT(partition.devicePath() == pedDevice()->path);
qint32 rval = -1;
QString rval = "";
// 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
@ -165,7 +165,7 @@ qint32 LibPartedPartitionTable::createPartition(Report& report, const Partition&
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;
return "";
}
PedFileSystemType* pedFsType = (partition.roles().has(PartitionRole::Extended) || partition.fileSystem().type() == FileSystem::Unformatted) ? NULL : getPedFileSystemType(partition.fileSystem().type());
@ -175,7 +175,7 @@ qint32 LibPartedPartitionTable::createPartition(Report& report, const Partition&
if (pedPartition == NULL)
{
report.line() << i18nc("@info/plain", "Failed to create new partition <filename>%1</filename>.", partition.deviceNode());
return false;
return "";
}
PedConstraint* pedConstraint = NULL;
@ -187,11 +187,11 @@ qint32 LibPartedPartitionTable::createPartition(Report& report, const Partition&
if (pedConstraint == NULL)
{
report.line() << i18nc("@info/plain", "Failed to create a new partition: could not get geometry for constraint.");
return -1;
return "";
}
if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint))
rval = pedPartition->num;
rval = QString(ped_partition_get_path(pedPartition));
else
report.line() << i18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition.deviceNode(), pedDisk()->dev->path);

View File

@ -48,7 +48,7 @@ class LibPartedPartitionTable : public CoreBackendPartitionTable
virtual CoreBackendPartition* getExtendedPartition();
virtual CoreBackendPartition* getPartitionBySector(qint64 sector);
virtual qint32 createPartition(Report& report, const Partition& partition);
virtual QString createPartition(Report& report, const Partition& partition);
virtual bool deletePartition(Report& report, const Partition& partition);
virtual bool updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end);
virtual bool clobberFileSystem(Report& report, const Partition& partition);