solid: use socket notifier to watch for /etc/mtab changes

in the proc man page (man 5 proc) /proc/pid/mounts is documented to be
pollable and trigger exception when changed, the current solution for the
accessibility signal remains process namespace restricted

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-15 06:55:01 +03:00
parent 57df231a13
commit f79ff0e685
2 changed files with 24 additions and 22 deletions

View file

@ -20,6 +20,7 @@
#include "udevstorageaccess.h" #include "udevstorageaccess.h"
#include "kmountpoint.h" #include "kmountpoint.h"
#include "kde_file.h"
#include <QDBusInterface> #include <QDBusInterface>
#include <QDBusReply> #include <QDBusReply>
@ -29,21 +30,29 @@ using namespace Solid::Backends::UDev;
StorageAccess::StorageAccess(UDevDevice *device) StorageAccess::StorageAccess(UDevDevice *device)
: DeviceInterface(device), : DeviceInterface(device),
m_isaccessible(false) m_mtabfd(0),
m_isaccessible(false),
m_mtabnotifier(nullptr)
{ {
m_isaccessible = isAccessible(); m_isaccessible = isAccessible();
// NOTE: stat() always returns the same result for it if actually in /proc/self/mounts m_mtabfd = KDE_open("/etc/mtab", O_RDONLY);
m_mtabfile.setFileName("/etc/mtab"); if (m_mtabfd <= 0) {
if (m_mtabfile.open(QFile::ReadOnly)) { qWarning("StorageAccess: unable to open /etc/mtab");
m_mtabtimer.setInterval(2000); return;
m_mtabtimer.start();
QObject::connect(&m_mtabtimer, SIGNAL(timeout()), this, SLOT(slotEmitSignals()));
} }
m_mtabnotifier = new QSocketNotifier(m_mtabfd, QSocketNotifier::Exception);
QObject::connect(m_mtabnotifier, SIGNAL(activated(int)), this, SLOT(slotEmitSignals()));
} }
StorageAccess::~StorageAccess() StorageAccess::~StorageAccess()
{ {
if (m_mtabnotifier) {
delete m_mtabnotifier;
}
if (m_mtabfd > 0) {
QT_CLOSE(m_mtabfd);
}
} }
bool StorageAccess::isAccessible() const bool StorageAccess::isAccessible() const
@ -140,15 +149,10 @@ bool StorageAccess::teardown()
void StorageAccess::slotEmitSignals() void StorageAccess::slotEmitSignals()
{ {
const QByteArray previousmtabdata = m_mtabdata; const bool previousisaccessible = m_isaccessible;
m_mtabfile.seek(0); m_isaccessible = isAccessible();
m_mtabdata = m_mtabfile.readAll(); // qDebug() << Q_FUNC_INFO << m_mtabfd << previousisaccessible << m_isaccessible;
// qDebug() << Q_FUNC_INFO << m_mtabdata; if (previousisaccessible != m_isaccessible) {
if (previousmtabdata != m_mtabdata) { emit accessibilityChanged(m_isaccessible, m_device->udi());
const bool previousisaccessible = m_isaccessible;
m_isaccessible = isAccessible();
if (previousisaccessible != m_isaccessible) {
emit accessibilityChanged(m_isaccessible, m_device->udi());
}
} }
} }

View file

@ -24,8 +24,7 @@
#include <solid/ifaces/storageaccess.h> #include <solid/ifaces/storageaccess.h>
#include "udevdeviceinterface.h" #include "udevdeviceinterface.h"
#include <QFile> #include <QSocketNotifier>
#include <QTimer>
namespace Solid namespace Solid
{ {
@ -59,10 +58,9 @@ private Q_SLOTS:
void slotEmitSignals(); void slotEmitSignals();
private: private:
QTimer m_mtabtimer; int m_mtabfd;
QFile m_mtabfile;
QByteArray m_mtabdata;
bool m_isaccessible; bool m_isaccessible;
QSocketNotifier* m_mtabnotifier;
}; };
} }
} }