8#include "fstabhandling.h"
9#include "fstab_debug.h"
14#include <QRegularExpression>
15#include <QStandardPaths>
17#include <QThreadStorage>
19#include <solid/devices/soliddefs_p.h>
21#include <solid/config-solid.h>
25#include <sys/mnttab.h>
29#elif defined(HAVE_SYS_MNTENT_H)
30#include <sys/mntent.h>
45#define FSTAB "/etc/vfstab"
47#define FSTAB "/etc/fstab"
54#define MNTTAB _PATH_MOUNTED
58#define MNTTAB MTAB_FILE
60#define MNTTAB "/etc/mnttab"
73#define SETMNTENT setmntent
74#define ENDMNTENT endmntent
75#define STRUCT_MNTENT struct mntent *
76#define STRUCT_SETMNTENT FILE *
77#define GETMNTENT(file, var) ((var = getmntent(file)) != nullptr)
78#define MOUNTPOINT(var) var->mnt_dir
79#define MOUNTTYPE(var) var->mnt_type
80#define MOUNTOPTIONS(var) var->mnt_opts
81#define FSNAME(var) var->mnt_fsname
83#define SETMNTENT fopen
84#define ENDMNTENT fclose
85#define STRUCT_MNTENT struct mnttab
86#define STRUCT_SETMNTENT FILE *
87#define GETMNTENT(file, var) (getmntent(file, &var) == nullptr)
88#define MOUNTPOINT(var) var.mnt_mountp
89#define MOUNTTYPE(var) var.mnt_fstype
90#define MOUNTOPTIONS(var) var.mnt_mntopts
91#define FSNAME(var) var.mnt_special
96Solid::Backends::Fstab::FstabHandling::FstabHandling()
97 : m_fstabCacheValid(false)
98 , m_mtabCacheValid(false)
102bool _k_isFstabNetworkFileSystem(
const QString &fstype,
const QString &devName)
109 || fstype ==
"fuse.sshfs"
116bool _k_isFstabSupportedLocalFileSystem(
const QString &fstype)
118 if (fstype ==
"fuse.encfs"
119 || fstype ==
"fuse.cryfs"
120 || fstype ==
"fuse.gocryptfs"
121 || fstype ==
"overlay") {
130 return fstype + mountpoint;
137 auto _mountpoint = mountpoint;
138 if (fstype ==
"nfs" || fstype ==
"nfs4") {
147void Solid::Backends::Fstab::FstabHandling::_k_updateFstabMountPointsCache()
149 if (globalFstabCache->localData().m_fstabCacheValid) {
153 globalFstabCache->localData().m_fstabCache.clear();
154 globalFstabCache->localData().m_fstabOptionsCache.clear();
159 if ((fstab = setmntent(FSTAB,
"r")) ==
nullptr) {
164 while ((fe = getmntent(fstab)) !=
nullptr) {
167 if (_k_isFstabNetworkFileSystem(fstype, fsname) || _k_isFstabSupportedLocalFileSystem(fstype)) {
169 const QString device = _k_deviceNameForMountpoint(fsname, fstype, mountpoint);
172 globalFstabCache->localData().m_fstabCache.
insert(device, mountpoint);
173 globalFstabCache->localData().m_fstabFstypeCache.insert(device, fstype);
175 globalFstabCache->localData().m_fstabOptionsCache.insert(device, options.
takeFirst());
192 while (!stream.atEnd()) {
202 if (items.
count() < 5) {
206 if (items.
count() < 4) {
211 if (_k_isFstabNetworkFileSystem(items.
at(2), items.
at(0)) || _k_isFstabSupportedLocalFileSystem(items.
at(2))) {
216 if (fsType ==
"nfs" || fsType ==
"nfs4") {
223 globalFstabCache->localData().m_fstabCache.
insert(device, mountpoint);
229 globalFstabCache->localData().m_fstabCacheValid =
true;
232QStringList Solid::Backends::Fstab::FstabHandling::deviceList()
234 _k_updateFstabMountPointsCache();
235 _k_updateMtabMountPointsCache();
237 QStringList devices = globalFstabCache->localData().m_mtabCache.keys();
242 for (
auto it = globalFstabCache->localData().m_fstabCache.constBegin(), end = globalFstabCache->localData().m_fstabCache.constEnd(); it !=
end; ++it) {
243 auto device = it.key();
256 if (!devices.
contains(deviceName)) {
265 _k_updateFstabMountPointsCache();
266 _k_updateMtabMountPointsCache();
268 QStringList mountpoints = globalFstabCache->localData().m_fstabCache.values(device);
269 mountpoints += globalFstabCache->localData().m_mtabCache.values(device);
276 _k_updateFstabMountPointsCache();
278 QStringList options = globalFstabCache->localData().m_fstabOptionsCache.values(device);
282QString Solid::Backends::Fstab::FstabHandling::fstype(
const QString &device)
284 _k_updateFstabMountPointsCache();
286 return globalFstabCache->localData().m_fstabFstypeCache.value(device);
289bool Solid::Backends::Fstab::FstabHandling::callSystemCommand(
const QString &commandName,
292 std::function<
void(
QProcess *)> callback)
294 static const QStringList searchPaths{QStringLiteral(
"/sbin"), QStringLiteral(
"/bin"), QStringLiteral(
"/usr/sbin"), QStringLiteral(
"/usr/bin")};
298 qCWarning(FSTAB_LOG) <<
"Couldn't find executable " + commandName +
" in " + joinedPaths;
309 Q_UNUSED(exitStatus);
318 process->
start(exec, args);
328void Solid::Backends::Fstab::FstabHandling::_k_updateMtabMountPointsCache()
330 if (globalFstabCache->localData().m_mtabCacheValid) {
334 globalFstabCache->localData().m_mtabCache.clear();
338#if GETMNTINFO_USES_STATVFS
339 struct statvfs *mounted;
341 struct statfs *mounted;
344 int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
346 for (
int i = 0; i < num_fs; i++) {
348 if (_k_isFstabNetworkFileSystem(type,
QString()) || _k_isFstabSupportedLocalFileSystem(type)) {
351 const QString device = _k_deviceNameForMountpoint(fsname, type, mountpoint);
352 globalFstabCache->localData().m_mtabCache.insert(device, mountpoint);
353 globalFstabCache->localData().m_fstabFstypeCache.insert(device, type);
358 STRUCT_SETMNTENT mnttab;
359 if ((mnttab = SETMNTENT(MNTTAB,
"r")) ==
nullptr) {
364 while (GETMNTENT(mnttab, fe)) {
366 if (_k_isFstabNetworkFileSystem(type,
QString()) || _k_isFstabSupportedLocalFileSystem(type)) {
369 const QString device = _k_deviceNameForMountpoint(fsname, type, mountpoint);
370 globalFstabCache->localData().m_mtabCache.insert(device, mountpoint);
371 globalFstabCache->localData().m_fstabFstypeCache.insert(device, type);
377 globalFstabCache->localData().m_mtabCacheValid =
true;
380QStringList Solid::Backends::Fstab::FstabHandling::currentMountPoints(
const QString &device)
382 _k_updateMtabMountPointsCache();
383 return globalFstabCache->localData().m_mtabCache.values(device);
386void Solid::Backends::Fstab::FstabHandling::flushMtabCache()
388 globalFstabCache->localData().m_mtabCacheValid =
false;
391void Solid::Backends::Fstab::FstabHandling::flushFstabCache()
393 globalFstabCache->localData().m_fstabCacheValid =
false;
Type type(const QSqlDatabase &db)
const QList< QKeySequence > & end()
QString decodeName(const QByteArray &localFileName)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype count() const const
iterator insert(const_iterator before, parameter_type value)
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setEnvironment(const QStringList &environment)
void finished(int exitCode, QProcess::ExitStatus exitStatus)
void start(OpenMode mode)
QStringList systemEnvironment()
bool waitForStarted(int msecs)
QString findExecutable(const QString &executableName, const QStringList &paths)
QString & append(QChar ch)
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString & insert(qsizetype position, QChar ch)
bool isEmpty() const const
QString & prepend(QChar ch)
QString simplified() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
qsizetype removeDuplicates()
QStringList & replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)