Add support for resizing online.

This commit is contained in:
Andrius Štikonas 2016-08-08 02:01:35 +01:00
parent 4bb370bffc
commit 4d25524e91
18 changed files with 149 additions and 13 deletions

View File

@ -164,6 +164,18 @@ bool btrfs::resize(Report& report, const QString& deviceNode, qint64 length) con
return rval;
}
bool btrfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const
{
ExternalCommand resizeCmd(report, QStringLiteral("btrfs"),
{ QStringLiteral("filesystem"), QStringLiteral("resize"), QString::number(length), mountPoint });
if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0)
return true;
report.line() << xi18nc("@info:progress", "Resizing Btrfs file system on partition <filename>%1</filename> failed: btrfs file system resize failed.", deviceNode);
return false;
}
bool btrfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
{
ExternalCommand cmd(report, QStringLiteral("btrfs"), { QStringLiteral("filesystem"), QStringLiteral("label"), deviceNode, newLabel });

View File

@ -47,6 +47,7 @@ public:
bool check(Report& report, const QString& deviceNode) const override;
bool create(Report& report, const QString& deviceNode) const override;
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
bool updateUUID(Report& report, const QString& deviceNode) const override;
@ -62,9 +63,15 @@ public:
CommandSupportType supportGrow() const override {
return m_Grow;
}
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
CommandSupportType supportShrink() const override {
return m_Shrink;
}
CommandSupportType supportShrinkOnline() const override {
return m_Shrink;
}
CommandSupportType supportMove() const override {
return m_Move;
}

View File

@ -39,4 +39,9 @@ bool ext3::create(Report& report, const QString& deviceNode) const
ExternalCommand cmd(report, QStringLiteral("mkfs.ext3"), QStringList() << QStringLiteral("-qF") << deviceNode);
return cmd.run(-1) && cmd.exitCode() == 0;
}
bool ext3::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
{
return resize(report, deviceNode, length);
}
}

View File

@ -44,7 +44,12 @@ public:
public:
bool create(Report& report, const QString& deviceNode) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
qint64 maxCapacity() const override;
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
};
}

View File

@ -39,4 +39,9 @@ bool ext4::create(Report& report, const QString& deviceNode) const
ExternalCommand cmd(report, QStringLiteral("mkfs.ext4"), QStringList() << QStringLiteral("-qF") << deviceNode);
return cmd.run(-1) && cmd.exitCode() == 0;
}
bool ext4::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
{
return resize(report, deviceNode, length);
}
}

View File

@ -44,7 +44,12 @@ public:
public:
bool create(Report& report, const QString& deviceNode) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
qint64 maxCapacity() const override;
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
};
}

View File

@ -153,6 +153,24 @@ bool FileSystem::resize(Report& report, const QString& deviceNode, qint64 newLen
return true;
}
/** Resize a mounted FileSystem to a given new length
@param report Report to write status information to
@param deviceNode the device node for the Partition the FileSystem is on
@param mountPoint the mount point where FileSystem is mounted on
@param newLength the new length for the FileSystem in bytes
@return true on success
*/
bool FileSystem::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const
{
Q_UNUSED(report);
Q_UNUSED(deviceNode);
Q_UNUSED(mountPoint);
Q_UNUSED(newLength);
return true;
}
/** Move a FileSystem to a new start sector
@param report Report to write status information to
@param deviceNode the device node for the Partition the FileSystem is on

View File

@ -22,11 +22,11 @@
#define FILESYSTEM__H
#include "util/libpartitionmanagerexport.h"
#include <QtGlobal>
#include <QColor>
#include <QList>
#include <QStringList>
#include <QString>
#include <QList>
#include <QtGlobal>
#include <QUrl>
#include <array>
@ -112,6 +112,7 @@ public:
virtual QString readLabel(const QString& deviceNode) const;
virtual bool create(Report& report, const QString& deviceNode) const;
virtual bool resize(Report& report, const QString& deviceNode, qint64 newLength) const;
virtual bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const;
virtual bool move(Report& report, const QString& deviceNode, qint64 newStartSector) const;
virtual bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel);
virtual bool copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const;
@ -134,9 +135,15 @@ public:
virtual CommandSupportType supportGrow() const {
return cmdSupportNone; /**< @return CommandSupportType for growing */
}
virtual CommandSupportType supportGrowOnline() const {
return cmdSupportNone; /**< @return CommandSupportType for online growing */
}
virtual CommandSupportType supportShrink() const {
return cmdSupportNone; /**< @return CommandSupportType for shrinking */
}
virtual CommandSupportType supportShrinkOnline() const {
return cmdSupportNone; /**< @return CommandSupportType for shrinking */
}
virtual CommandSupportType supportMove() const {
return cmdSupportNone; /**< @return CommandSupportType for moving */
}

View File

@ -162,12 +162,12 @@ bool jfs::resize(Report& report, const QString& deviceNode, qint64) const
bool rval = false;
ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("-v"), QStringLiteral("-t"), QStringLiteral("jfs"), deviceNode, tempDir.path() });
ExternalCommand mountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), deviceNode, tempDir.path() });
if (mountCmd.run(-1)) {
ExternalCommand resizeMountCmd(report, QStringLiteral("mount"), { QStringLiteral("-v"), QStringLiteral("-t"), QStringLiteral("jfs"), QStringLiteral("-o"), QStringLiteral("remount,resize"), deviceNode, tempDir.path() });
ExternalCommand resizeMountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), QStringLiteral("--options"), QStringLiteral("remount,resize"), deviceNode, tempDir.path() });
if (resizeMountCmd.run(-1))
if (resizeMountCmd.run(-1) && resizeMountCmd.exitCode() == 0)
rval = true;
else
report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition <filename>%1</filename> failed: Remount failed.", deviceNode);
@ -181,4 +181,15 @@ bool jfs::resize(Report& report, const QString& deviceNode, qint64) const
return rval;
}
bool jfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64) const
{
ExternalCommand resizeMountCmd(report, QStringLiteral("mount"), { QStringLiteral("--verbose"), QStringLiteral("--type"), QStringLiteral("jfs"), QStringLiteral("--options"), QStringLiteral("remount,resize"), deviceNode, mountPoint });
if (resizeMountCmd.run(-1) && resizeMountCmd.exitCode() == 0)
return true;
report.line() << xi18nc("@info:progress", "Resizing JFS file system on partition <filename>%1</filename> failed: Remount failed.", deviceNode);
return false;
}
}

View File

@ -46,6 +46,7 @@ public:
bool check(Report& report, const QString& deviceNode) const override;
bool create(Report& report, const QString& deviceNode) const override;
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
CommandSupportType supportGetUsed() const override {
@ -60,6 +61,9 @@ public:
CommandSupportType supportGrow() const override {
return m_Grow;
}
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
CommandSupportType supportMove() const override {
return m_Move;
}

View File

@ -169,6 +169,17 @@ bool nilfs2::resize(Report& report, const QString& deviceNode, qint64 length) co
return rval;
}
bool nilfs2::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
{
ExternalCommand resizeCmd(report, QStringLiteral("nilfs-resize"), { QStringLiteral("--verbose"), QStringLiteral("--assume-yes"), deviceNode, QString::number(length) });
if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0)
return true;
report.line() << xi18nc("@info:progress", "Resizing NILFS2 file system on partition <filename>%1</filename> failed: NILFS2 file system resize failed.", deviceNode);
return false;
}
bool nilfs2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
{
ExternalCommand cmd(report, QStringLiteral("nilfs-tune"), { QStringLiteral("-l"), newLabel, deviceNode });

View File

@ -48,6 +48,7 @@ public:
bool create(Report& report, const QString& deviceNode) const override;
qint64 readUsedCapacity(const QString& deviceNode) const override;
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
bool updateUUID(Report& report, const QString& deviceNode) const override;
@ -63,9 +64,15 @@ public:
CommandSupportType supportGrow() const override {
return m_Grow;
}
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
CommandSupportType supportShrink() const override {
return m_Shrink;
}
CommandSupportType supportShrinkOnline() const override {
return m_Shrink;
}
CommandSupportType supportMove() const override {
return m_Move;
}

View File

@ -165,6 +165,11 @@ bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length)
return cmd.waitFor(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 256);
}
bool reiserfs::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
{
return resize(report, deviceNode, length);
}
bool reiserfs::updateUUID(Report& report, const QString& deviceNode) const
{
const QString uuid = QUuid::createUuid().toString().remove(QRegularExpression(QStringLiteral("\\{|\\}")));

View File

@ -48,6 +48,7 @@ public:
bool check(Report& report, const QString& deviceNode) const override;
bool create(Report& report, const QString& deviceNode) const override;
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
bool updateUUID(Report& report, const QString& deviceNode) const override;
@ -63,6 +64,9 @@ public:
CommandSupportType supportGrow() const override {
return m_Grow;
}
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
CommandSupportType supportShrink() const override {
return m_Shrink;
}

View File

@ -177,7 +177,7 @@ bool xfs::resize(Report& report, const QString& deviceNode, qint64) const
if (mountCmd.run(-1)) {
ExternalCommand resizeCmd(report, QStringLiteral("xfs_growfs"), { tempDir.path() });
if (resizeCmd.run(-1))
if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0)
rval = true;
else
report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition <filename>%1</filename> failed: xfs_growfs failed.", deviceNode);
@ -191,4 +191,15 @@ bool xfs::resize(Report& report, const QString& deviceNode, qint64) const
return rval;
}
bool xfs::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64) const
{
ExternalCommand resizeCmd(report, QStringLiteral("xfs_growfs"), { mountPoint });
if (resizeCmd.run(-1) && resizeCmd.exitCode() == 0)
return true;
report.line() << xi18nc("@info:progress", "Resizing XFS file system on partition <filename>%1</filename> failed: xfs_growfs failed.", deviceNode);
return false;
}
}

View File

@ -47,6 +47,7 @@ public:
bool create(Report& report, const QString& deviceNode) const override;
bool copy(Report& report, const QString&, const QString&) const override;
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
bool resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 length) const override;
bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
CommandSupportType supportGetUsed() const override {
@ -61,6 +62,9 @@ public:
CommandSupportType supportGrow() const override {
return m_Grow;
}
CommandSupportType supportGrowOnline() const override {
return m_Grow;
}
CommandSupportType supportMove() const override {
return m_Move;
}

View File

@ -87,7 +87,10 @@ bool ResizeFileSystemJob::run(Report& parent)
case FileSystem::cmdSupportFileSystem: {
const qint64 newLengthInByte = Capacity(newLength() * device().logicalSectorSize()).toInt(Capacity::Byte);
rval = partition().fileSystem().resize(*report, partition().deviceNode(), newLengthInByte);
if (partition().isMounted())
rval = partition().fileSystem().resizeOnline(*report, partition().deviceNode(), partition().mountPoint(), newLengthInByte);
else
rval = partition().fileSystem().resize(*report, partition().deviceNode(), newLengthInByte);
break;
}

View File

@ -63,7 +63,8 @@ ResizeOperation::ResizeOperation(Device& d, Partition& p, qint64 newfirst, qint6
m_GrowSetGeomJob(nullptr),
m_CheckResizedJob(nullptr)
{
addJob(checkOriginalJob());
if(!partition().isMounted()) // FIXME: add support for checkOnline for file systems that support it.
addJob(checkOriginalJob());
if (partition().roles().has(PartitionRole::Extended)) {
m_MoveExtendedJob = new SetPartGeometryJob(targetDevice(), partition(), newFirstSector(), newLength());
@ -99,7 +100,8 @@ ResizeOperation::ResizeOperation(Device& d, Partition& p, qint64 newfirst, qint6
m_CheckResizedJob = new CheckFileSystemJob(partition());
addJob(checkResizedJob());
if(!partition().isMounted()) // FIXME: add support for checkOnline for file systems that support it.
addJob(checkResizedJob());
}
}
@ -145,7 +147,12 @@ bool ResizeOperation::execute(Report& parent)
Report* report = parent.newChild(description());
if ((rval = checkOriginalJob()->run(*report))) {
if (partition().isMounted()) // FIXME: add support for checkOnline for file systems that support it.
rval = true;
else
rval = checkOriginalJob()->run(*report);
if (rval) {
// Extended partitions are a special case: They don't have any file systems and so there's no
// need to move, shrink or grow their contents before setting the new geometry. In fact, trying
// to first shrink THEN move would not work for an extended partition that has children, because
@ -158,7 +165,12 @@ bool ResizeOperation::execute(Report& parent)
rval = shrink(*report) && move(*report) && grow(*report);
if (rval) {
if (!(rval = checkResizedJob()->run(*report)))
if (partition().isMounted()) // FIXME: add support for checkOnline for file systems that support it.
rval = true;
else
rval = checkResizedJob()->run(*report);
if (!rval)
report->line() << xi18nc("@info:status", "Checking partition <filename>%1</filename> after resize/move failed.", partition().deviceNode());
} else
report->line() << xi18nc("@info:status", "Resizing/moving partition <filename>%1</filename> failed.", partition().deviceNode());
@ -327,7 +339,7 @@ bool ResizeOperation::canGrow(const Partition* p)
return true;
if (p->isMounted())
return false;
return p->fileSystem().supportGrowOnline();
return p->fileSystem().supportGrow() != FileSystem::cmdSupportNone;
}
@ -349,7 +361,7 @@ bool ResizeOperation::canShrink(const Partition* p)
return false;
if (p->isMounted())
return false;
return p->fileSystem().supportShrinkOnline();
return p->fileSystem().supportShrink() != FileSystem::cmdSupportNone;
}