File indexing completed on 2024-05-05 05:48:47

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
0003     SPDX-FileCopyrightText: 2012-2018 Andrius Štikonas <andrius@stikonas.eu>
0004     SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
0005     SPDX-FileCopyrightText: 2019 Yuri Chornoivan <yurchor@ukr.net>
0006     SPDX-FileCopyrightText: 2020 Arnaud Ferraris <arnaud.ferraris@collabora.com>
0007     SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
0008 
0009     SPDX-License-Identifier: GPL-3.0-or-later
0010 */
0011 
0012 #include "fs/ocfs2.h"
0013 
0014 #include "util/externalcommand.h"
0015 #include "util/capacity.h"
0016 
0017 #include <QRegularExpression>
0018 #include <QString>
0019 
0020 namespace FS
0021 {
0022 FileSystem::CommandSupportType ocfs2::m_GetUsed = FileSystem::cmdSupportNone;
0023 FileSystem::CommandSupportType ocfs2::m_GetLabel = FileSystem::cmdSupportNone;
0024 FileSystem::CommandSupportType ocfs2::m_Create = FileSystem::cmdSupportNone;
0025 FileSystem::CommandSupportType ocfs2::m_Grow = FileSystem::cmdSupportNone;
0026 FileSystem::CommandSupportType ocfs2::m_Shrink = FileSystem::cmdSupportNone;
0027 FileSystem::CommandSupportType ocfs2::m_Move = FileSystem::cmdSupportNone;
0028 FileSystem::CommandSupportType ocfs2::m_Check = FileSystem::cmdSupportNone;
0029 FileSystem::CommandSupportType ocfs2::m_Copy = FileSystem::cmdSupportNone;
0030 FileSystem::CommandSupportType ocfs2::m_Backup = FileSystem::cmdSupportNone;
0031 FileSystem::CommandSupportType ocfs2::m_SetLabel = FileSystem::cmdSupportNone;
0032 FileSystem::CommandSupportType ocfs2::m_UpdateUUID = FileSystem::cmdSupportNone;
0033 FileSystem::CommandSupportType ocfs2::m_GetUUID = FileSystem::cmdSupportNone;
0034 
0035 ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
0036     FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ocfs2)
0037 {
0038 }
0039 
0040 void ocfs2::init()
0041 {
0042     m_Create = findExternal(QStringLiteral("mkfs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : cmdSupportNone;
0043     m_Check = findExternal(QStringLiteral("fsck.ocfs2"), {}, 16) ? cmdSupportFileSystem : cmdSupportNone;
0044     m_Grow = (m_Check != cmdSupportNone && findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) && findExternal(QStringLiteral("debugfs.ocfs2"), { QStringLiteral("--version") })) ? cmdSupportFileSystem : cmdSupportNone;
0045     m_Shrink = cmdSupportNone;
0046 
0047     // TODO: it seems there's no way to get the FS usage with ocfs2
0048     m_GetUsed = cmdSupportNone;
0049 
0050     m_SetLabel = findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : cmdSupportNone;
0051     m_UpdateUUID = findExternal(QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--version") }) ? cmdSupportFileSystem : cmdSupportNone;
0052 
0053     m_Copy = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone;
0054     m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone;
0055 
0056     m_GetLabel = cmdSupportCore;
0057     m_Backup = cmdSupportCore;
0058     m_GetUUID = cmdSupportCore;
0059 }
0060 
0061 bool ocfs2::supportToolFound() const
0062 {
0063     return
0064 //          m_GetUsed != cmdSupportNone &&
0065         m_GetLabel != cmdSupportNone &&
0066         m_SetLabel != cmdSupportNone &&
0067         m_Create != cmdSupportNone &&
0068         m_Check != cmdSupportNone &&
0069         m_UpdateUUID != cmdSupportNone &&
0070         m_Grow != cmdSupportNone &&
0071 //          m_Shrink != cmdSupportNone &&
0072         m_Copy != cmdSupportNone &&
0073         m_Move != cmdSupportNone &&
0074         m_Backup != cmdSupportNone &&
0075         m_GetUUID != cmdSupportNone;
0076 }
0077 
0078 FileSystem::SupportTool ocfs2::supportToolName() const
0079 {
0080     return SupportTool(QStringLiteral("ocfs2-tools"), QUrl(QStringLiteral("https://oss.oracle.com/projects/ocfs2-tools/")));
0081 }
0082 
0083 qint64 ocfs2::minCapacity() const
0084 {
0085     return 14000 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::KiB);
0086 }
0087 
0088 qint64 ocfs2::maxCapacity() const
0089 {
0090     return 4 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::PiB);
0091 }
0092 
0093 qint64 ocfs2::readUsedCapacity(const QString& deviceNode) const
0094 {
0095     Q_UNUSED(deviceNode)
0096     return -1;
0097 }
0098 
0099 bool ocfs2::check(Report& report, const QString& deviceNode) const
0100 {
0101     ExternalCommand cmd(report, QStringLiteral("fsck.ocfs2"), { QStringLiteral("-f"), QStringLiteral("-y"), deviceNode });
0102     return cmd.run(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 1 || cmd.exitCode() == 2);
0103 }
0104 
0105 bool ocfs2::create(Report& report, const QString& deviceNode)
0106 {
0107     ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode });
0108 
0109     cmd.write("y\n");
0110     if (!cmd.start())
0111         return false;
0112 
0113     return cmd.exitCode() == 0;
0114 
0115 }
0116 
0117 bool ocfs2::resize(Report& report, const QString& deviceNode, qint64 length) const
0118 {
0119     ExternalCommand cmdBlockSize(QStringLiteral("debugfs.ocfs2"), { QStringLiteral("--request"), QStringLiteral("stats"), deviceNode });
0120 
0121     qint32 blockSize = -1;
0122     if (cmdBlockSize.run(-1) && cmdBlockSize.exitCode() == 0) {
0123         QRegularExpression re(QStringLiteral("Block Size Bits: (\\d+)"));
0124         QRegularExpressionMatch reBlockSizeBits = re.match(cmdBlockSize.output());
0125 
0126         if (reBlockSizeBits.hasMatch())
0127             blockSize = 1 << reBlockSizeBits.captured(1).toInt();
0128     }
0129 
0130     if (blockSize == -1)
0131         return false;
0132 
0133     ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--yes"), QStringLiteral("--volume-size"), deviceNode, QString::number(length / blockSize) });
0134     return cmd.run(-1) && cmd.exitCode() == 0;
0135 }
0136 
0137 bool ocfs2::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
0138 {
0139     ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--label"), newLabel, deviceNode });
0140     return cmd.run(-1) && cmd.exitCode() == 0;
0141 }
0142 
0143 bool ocfs2::updateUUID(Report& report, const QString& deviceNode) const
0144 {
0145     ExternalCommand cmd(report, QStringLiteral("tunefs.ocfs2"), { QStringLiteral("--uuid-reset"), deviceNode });
0146     return cmd.run(-1) && cmd.exitCode() == 0;
0147 }
0148 }