Skip to content

Commit

Permalink
[systemsettings] Make Udisks monitor to track "org.feedesktop.UDisks2…
Browse files Browse the repository at this point in the history
….Filesystem" interface changes. Contributes to JB#42527

Udisks monitor now keeps track on "org.freedesktop.UDisks2.Filesystem" changes
meaning that when file system is added, block becomes mountable and
when file system is removed, block can no longer be mounted as per
udisks documentation says.

This commit also changes formatted state change so that we enter to
formatted state only after file system reappears after formatting.
  • Loading branch information
rainemak committed Aug 24, 2018
1 parent abb9dfd commit 0c747bc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 28 deletions.
22 changes: 21 additions & 1 deletion src/udisks2block.cpp
Expand Up @@ -13,6 +13,7 @@ UDisks2::Block::Block(const QString &path, const QVariantMap &data, QObject *par
, m_data(data)
, m_connection(QDBusConnection::systemBus())
, m_mountable(false)
, m_formatting(false)
, m_pendingFileSystem(nullptr)
, m_pendingBlock(nullptr)
{
Expand Down Expand Up @@ -113,7 +114,26 @@ qint64 UDisks2::Block::size() const

bool UDisks2::Block::isMountable() const
{
return m_mountable;
return m_mountable && value(QStringLiteral("HintAuto")).toBool();
}

void UDisks2::Block::setMountable(bool mountable)
{
if (m_mountable != mountable) {
m_mountable = mountable;

if (m_mountable && m_formatting) {
m_formatting = false;
emit formatted();
}

emit updated();
}
}

void UDisks2::Block::setFormatting()
{
m_formatting = true;
}

bool UDisks2::Block::isReadOnly() const
Expand Down
6 changes: 6 additions & 0 deletions src/udisks2block_p.h
Expand Up @@ -60,6 +60,10 @@ class Block : public QObject
qint64 size() const;

bool isMountable() const;
void setMountable(bool mountable);

bool isFormatting() const;
void setFormatting();

bool isReadOnly() const;

Expand All @@ -77,6 +81,7 @@ class Block : public QObject
signals:
void completed();
void updated();
void formatted();
void mountPathChanged();

private slots:
Expand All @@ -91,6 +96,7 @@ private slots:
QDBusConnection m_connection;
QString m_mountPath;
bool m_mountable;
bool m_formatting;

QDBusPendingCallWatcher *m_pendingFileSystem;
QDBusPendingCallWatcher *m_pendingBlock;
Expand Down
69 changes: 42 additions & 27 deletions src/udisks2monitor.cpp
Expand Up @@ -117,7 +117,7 @@ UDisks2::Monitor::Monitor(PartitionManagerPrivate *manager, QObject *parent)
QStringLiteral("InterfacesRemoved"),
this,
SLOT(interfacesRemoved(QDBusObjectPath, QStringList)))) {
qCWarning(lcMemoryCardLog) << "Failed to connect to interfaces added signal:" << qPrintable(systemBus.lastError().message());
qCWarning(lcMemoryCardLog) << "Failed to connect to interfaces removed signal:" << qPrintable(systemBus.lastError().message());
}

getBlockDevices();
Expand Down Expand Up @@ -181,13 +181,20 @@ void UDisks2::Monitor::format(const QString &deviceName, const QString &type, co

void UDisks2::Monitor::interfacesAdded(const QDBusObjectPath &objectPath, const InterfaceAndPropertyMap &interfaces)
{
qCInfo(lcMemoryCardLog) << "Interface added:" << objectPath.path() << interfaces;
QString path = objectPath.path();
qCInfo(lcMemoryCardLog) << "UDisks interface added:" << path << interfaces;
// External device must have file system or partition so that it can added to the model.
// Devices without partition table have filesystem interface.
if ((interfaces.contains(UDISKS2_PARTITION_INTERFACE) || interfaces.contains(UDISKS2_FILESYSTEM_INTERFACE)) && externalBlockDevice(path)) {
QVariantMap dict = interfaces.value(UDISKS2_BLOCK_INTERFACE);
createBlockDevice(path, dict);
if (m_blockDevices.contains(path)) {
if (interfaces.contains(UDISKS2_FILESYSTEM_INTERFACE)) {
UDisks2::Block *block = m_blockDevices.value(path);
block->setMountable(true);
}
} else {
QVariantMap dict = interfaces.value(UDISKS2_BLOCK_INTERFACE);
createBlockDevice(path, dict);
}
} else if (path.startsWith(QStringLiteral("/org/freedesktop/UDisks2/jobs"))) {
QVariantMap dict = interfaces.value(UDISKS2_JOB_INTERFACE);
QString operation = dict.value(UDISKS2_JOB_KEY_OPERATION, QString()).toString();
Expand All @@ -205,24 +212,13 @@ void UDisks2::Monitor::interfacesAdded(const QDBusObjectPath &objectPath, const
m_jobsToWait.insert(path, job);
}
}

// object path "/org/freedesktop/UDisks2/block_devices/sda1"
// array [
// dict entry(
// string "org.freedesktop.UDisks2.Filesystem"

// Register monitor for this
// signal time=1521817375.168670 sender=:1.83 -> destination=(null destination) serial=199
// path=/org/freedesktop/UDisks2/block_devices/sda1; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
// string "org.freedesktop.UDisks2.Block"

}

void UDisks2::Monitor::interfacesRemoved(const QDBusObjectPath &objectPath, const QStringList &interfaces)
{
Q_UNUSED(interfaces)

QString path = objectPath.path();
qCInfo(lcMemoryCardLog) << "UDisks interface removed:" << path << interfaces;

if (m_jobsToWait.contains(path)) {
UDisks2::Job *job = m_jobsToWait.take(path);
job->deleteLater();
Expand All @@ -235,6 +231,9 @@ void UDisks2::Monitor::interfacesRemoved(const QDBusObjectPath &objectPath, cons
lookupPartitions(removedPartitions, blockDevPaths);
m_manager->remove(removedPartitions);
}
} else if (m_blockDevices.contains(path) && interfaces.contains(UDISKS2_FILESYSTEM_INTERFACE)) {
UDisks2::Block *block = m_blockDevices.value(path);
block->setMountable(false);
}
}

Expand All @@ -249,17 +248,16 @@ void UDisks2::Monitor::setPartitionProperties(QExplicitlySharedDataPointer<Parti
qCInfo(lcMemoryCardLog) << "- drive:" << blockDevice->drive() << "dNumber:" << blockDevice->deviceNumber();
qCInfo(lcMemoryCardLog) << "- id:" << blockDevice->id() << "size:" << blockDevice->size();
qCInfo(lcMemoryCardLog) << "- isreadonly:" << blockDevice->isReadOnly() << "idtype:" << blockDevice->idType();
qCInfo(lcMemoryCardLog) << "- idversion" << blockDevice->idVersion() << "idlabel" << blockDevice->idLabel();
qCInfo(lcMemoryCardLog) << "- iduuid" << blockDevice->idUUID();
qCInfo(lcMemoryCardLog) << "- idversion:" << blockDevice->idVersion() << "idlabel:" << blockDevice->idLabel();
qCInfo(lcMemoryCardLog) << "- iduuid:" << blockDevice->idUUID();
qCInfo(lcMemoryCardLog) << "- ismountable:" << blockDevice->isMountable() << "mount path:" << blockDevice->mountPath();

partition->devicePath = blockDevice->device();
partition->mountPath = blockDevice->mountPath();
partition->deviceLabel = label;
partition->filesystemType = blockDevice->idType();
partition->readOnly = blockDevice->isReadOnly();
partition->canMount = blockDevice->value(QStringLiteral("HintAuto")).toBool()
&& !partition->filesystemType.isEmpty()
&& m_manager->supportedFileSystems().contains(partition->filesystemType);
partition->canMount = blockDevice->isMountable() && m_manager->supportedFileSystems().contains(partition->filesystemType);
}

void UDisks2::Monitor::updatePartitionProperties(const UDisks2::Block *blockDevice)
Expand Down Expand Up @@ -319,10 +317,12 @@ void UDisks2::Monitor::updatePartitionStatus(const UDisks2::Job *job, bool succe
partition->filesystemType.clear();
partition->canMount = false;
partition->valid = false;
} else {
partition->activeState = QStringLiteral("inactive");
partition->status = Partition::Formatted;
partition->valid = true;

QString blockDevicePath = UDISKS2_BLOCK_DEVICE_PATH.arg(partition->deviceName);
if (m_blockDevices.contains(blockDevicePath)) {
Block *block = m_blockDevices.value(blockDevicePath);
block->setFormatting();
}
}
} else {
partition->activeState = QStringLiteral("failed");
Expand Down Expand Up @@ -472,7 +472,22 @@ void UDisks2::Monitor::createBlockDevice(const QString &path, const QVariantMap
}
});

// When e.g. partition formatted, partition info updated
connect(block, &UDisks2::Block::formatted, this, [this]() {
UDisks2::Block *block = qobject_cast<UDisks2::Block *>(sender());
QString blockPath = block->path();
if (m_blockDevices.contains(blockPath)) {
for (auto partition : m_manager->m_partitions) {
if (partition->devicePath == block->device()) {
partition->status = Partition::Formatted;
partition->activeState = QStringLiteral("inactive");
partition->valid = true;
m_manager->refresh(partition.data());
}
}
}
});

// When block info updated
connect(block, &UDisks2::Block::updated, this, [this]() {
UDisks2::Block *block = qobject_cast<UDisks2::Block *>(sender());
QString blockPath = block->path();
Expand Down

0 comments on commit 0c747bc

Please sign in to comment.