Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

Commit bc3d518

Browse files
committed
[nemo-storage] Make block devices without partition/partitiontable visible in model. Fixes JB#42943
This commit adds signleton block devices container that is the main interface that monitor uses for operating block devices. The block devices emits a signal (newBlock) when it sees an acceptable new block device and throws away the ones that cannot / should not be shown in the model. When block device container sees a block device that could be a container for a partition, it'll wait for 3000ms milliseconds before accepting the block. If partition appears during this inverval, then waiting is cancel.
1 parent e1d9073 commit bc3d518

11 files changed

+733
-366
lines changed

src/partitionmanager.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "partitionmanager_p.h"
3333
#include "udisks2monitor_p.h"
34+
#include "udisks2blockdevices_p.h"
3435
#include "logging_p.h"
3536

3637
#include <QFile>
@@ -340,7 +341,7 @@ QString PartitionManagerPrivate::objectPath(const QString &devicePath) const
340341
{
341342
QString deviceName = devicePath.section(QChar('/'), 2);
342343
if (externalMedia.match(deviceName).hasMatch()) {
343-
return m_udisksMonitor->instance()->objectPath(devicePath);
344+
return UDisks2::BlockDevices::instance()->objectPath(devicePath);
344345
} else {
345346
qCWarning(lcMemoryCardLog) << "Object path existing only for external memory cards:" << devicePath;
346347
return QString();

src/src.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SOURCES += \
3939
locationsettings.cpp \
4040
timezoneinfo.cpp \
4141
udisks2block.cpp \
42+
udisks2blockdevices.cpp \
4243
udisks2job.cpp \
4344
udisks2monitor.cpp
4445

@@ -78,6 +79,7 @@ HEADERS += \
7879
partition_p.h \
7980
partitionmanager_p.h \
8081
udisks2block_p.h \
82+
udisks2blockdevices_p.h \
8183
udisks2job_p.h \
8284
udisks2monitor_p.h
8385

src/udisks2block.cpp

Lines changed: 127 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap &
1717
, m_encrypted(interfacePropertyMap.contains(UDISKS2_ENCRYPTED_INTERFACE))
1818
, m_formatting(false)
1919
, m_locking(false)
20-
, m_pendingFileSystem(nullptr)
21-
, m_pendingBlock(nullptr)
22-
, m_pendingEncrypted(nullptr)
23-
, m_pendingDrive(nullptr)
2420
{
2521
if (!m_connection.connect(
2622
UDISKS2_SERVICE,
@@ -39,35 +35,61 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap &
3935

4036
qCInfo(lcMemoryCardLog) << "Creating a new block. Mountable:" << m_mountable << ", encrypted:" << m_encrypted << "object path:" << m_path << "data is empty:" << m_data.isEmpty();
4137

42-
if (m_data.isEmpty()) {
43-
getFileSystemInterface();
44-
getEncryptedInterface();
45-
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_BLOCK_INTERFACE);
46-
m_pendingBlock = new QDBusPendingCallWatcher(pendingCall, this);
47-
connect(m_pendingBlock, &QDBusPendingCallWatcher::finished, this, [this, path](QDBusPendingCallWatcher *watcher) {
48-
if (watcher->isValid() && watcher->isFinished()) {
49-
QDBusPendingReply<> reply = *watcher;
50-
QDBusMessage message = reply.reply();
51-
QVariantMap blockProperties = NemoDBus::demarshallArgument<QVariantMap>(message.arguments().at(0));
52-
qCInfo(lcMemoryCardLog) << "Block properties:" << blockProperties;
53-
m_data = blockProperties;
54-
getDriveProperties();
55-
} else {
56-
QDBusError error = watcher->error();
57-
qCWarning(lcMemoryCardLog) << "Error reading block properties:" << error.name() << error.message();
58-
}
59-
m_pendingBlock->deleteLater();
60-
m_pendingBlock = nullptr;
61-
complete();
38+
if (m_interfacePropertyMap.isEmpty()) {
39+
// Encrypted interface
40+
getProperties(m_path, UDISKS2_ENCRYPTED_INTERFACE, m_pendingEncrypted, [this](const QVariantMap &encryptedProperties) {
41+
m_encrypted = true;
42+
m_interfacePropertyMap.insert(UDISKS2_ENCRYPTED_INTERFACE, encryptedProperties);
43+
});
44+
45+
// File system interface
46+
getProperties(m_path, UDISKS2_FILESYSTEM_INTERFACE, m_pendingFileSystem, [this](const QVariantMap &filesystemProperties) {
47+
updateFileSystemInterface(filesystemProperties);
48+
});
49+
50+
// Partition table interface
51+
getProperties(m_path, UDISKS2_PARTITION_TABLE_INTERFACE, m_pendingPartitionTable, [this](const QVariantMap &partitionTableProperties) {
52+
m_interfacePropertyMap.insert(UDISKS2_PARTITION_TABLE_INTERFACE, partitionTableProperties);
53+
});
54+
55+
// Partition interface
56+
getProperties(m_path, UDISKS2_PARTITION_INTERFACE, m_pendingPartition, [this](const QVariantMap &partitionProperties) {
57+
m_interfacePropertyMap.insert(UDISKS2_PARTITION_INTERFACE, partitionProperties);
6258
});
59+
60+
// Block interface
61+
getProperties(m_path, UDISKS2_BLOCK_INTERFACE, m_pendingBlock, [this](const QVariantMap &blockProperties) {
62+
qCInfo(lcMemoryCardLog) << "Block properties:" << blockProperties;
63+
m_data = blockProperties;
64+
m_interfacePropertyMap.insert(UDISKS2_BLOCK_INTERFACE, blockProperties);
65+
66+
// Drive path is blocks property => doing it the callback.
67+
getProperties(drive(), UDISKS2_DRIVE_INTERFACE, m_pendingDrive, [this](const QVariantMap &driveProperties) {
68+
qCInfo(lcMemoryCardLog) << "Drive properties:" << driveProperties;
69+
m_drive = driveProperties;
70+
});
71+
72+
connect(m_pendingDrive.data(), &QObject::destroyed, this, &Block::complete);
73+
});
74+
75+
connect(m_pendingEncrypted.data(), &QObject::destroyed, this, &Block::complete);
76+
connect(m_pendingFileSystem.data(), &QObject::destroyed, this, &Block::complete);
77+
connect(m_pendingPartitionTable.data(), &QObject::destroyed, this, &Block::complete);
78+
connect(m_pendingPartition.data(), &QObject::destroyed, this, &Block::complete);
79+
connect(m_pendingBlock.data(), &QObject::destroyed, this, &Block::complete);
6380
} else {
6481
if (m_mountable) {
6582
QVariantMap map = interfacePropertyMap.value(UDISKS2_FILESYSTEM_INTERFACE);
66-
updateMountPoint(map);
83+
updateFileSystemInterface(map);
6784
}
68-
getDriveProperties();
6985

70-
// We have either org.freedesktop.UDisks2.Filesystem or org.freedesktop.UDisks2.Encrypted interface.
86+
getProperties(drive(), UDISKS2_DRIVE_INTERFACE, m_pendingDrive, [this](const QVariantMap &driveProperties) {
87+
qCInfo(lcMemoryCardLog) << "Drive properties:" << driveProperties;
88+
m_drive = driveProperties;
89+
});
90+
91+
if (m_pendingDrive)
92+
connect(m_pendingDrive.data(), &QObject::destroyed, this, &Block::complete);
7193
complete();
7294
}
7395

@@ -78,6 +100,7 @@ UDisks2::Block::Block(const QString &path, const UDisks2::InterfacePropertyMap &
78100

79101
UDisks2::Block &UDisks2::Block::operator=(const UDisks2::Block &)
80102
{
103+
return *this;
81104
}
82105

83106
UDisks2::Block::~Block()
@@ -125,6 +148,22 @@ QString UDisks2::Block::connectionBus() const
125148
return bus;
126149
}
127150

151+
QString UDisks2::Block::partitionTable() const
152+
{
153+
// Partion table that this partition belongs to.
154+
return NemoDBus::demarshallDBusArgument(m_interfacePropertyMap.value(UDISKS2_PARTITION_INTERFACE).value(QStringLiteral("Table"))).toString();
155+
}
156+
157+
bool UDisks2::Block::isPartition() const
158+
{
159+
return !m_interfacePropertyMap.value(UDISKS2_PARTITION_INTERFACE).isEmpty();
160+
}
161+
162+
bool UDisks2::Block::isPartitionTable() const
163+
{
164+
return !m_interfacePropertyMap.value(UDISKS2_PARTITION_TABLE_INTERFACE).isEmpty();
165+
}
166+
128167
qint64 UDisks2::Block::deviceNumber() const
129168
{
130169
return value(QStringLiteral("DeviceNumber")).toLongLong();
@@ -277,7 +316,9 @@ void UDisks2::Block::dumpInfo() const
277316
qCInfo(lcMemoryCardLog) << "- idversion:" << idVersion() << "idlabel:" << idLabel();
278317
qCInfo(lcMemoryCardLog) << "- iduuid:" << idUUID();
279318
qCInfo(lcMemoryCardLog) << "- ismountable:" << isMountable() << "mount path:" << mountPath();
280-
qCInfo(lcMemoryCardLog) << "- isencrypted:" << isEncrypted() << "crypto backing device:" << cryptoBackingDevicePath();
319+
qCInfo(lcMemoryCardLog) << "- isencrypted:" << isEncrypted() << "crypto backing device:" << cryptoBackingDevicePath() << "crypto backing object path:" << cryptoBackingDeviceObjectPath();
320+
qCInfo(lcMemoryCardLog) << "- isformatting:" << isFormatting();
321+
qCInfo(lcMemoryCardLog) << "- ispartiontable:" << isPartitionTable() << "ispartition:" << isPartition();
281322
}
282323

283324
QString UDisks2::Block::cryptoBackingDevicePath(const QString &objectPath)
@@ -309,11 +350,21 @@ void UDisks2::Block::removeInterface(const QString &interface)
309350
m_drive.clear();
310351
} else if (interface == UDISKS2_FILESYSTEM_INTERFACE) {
311352
setMountable(false);
312-
}else if (interface == UDISKS2_ENCRYPTED_INTERFACE) {
353+
} else if (interface == UDISKS2_ENCRYPTED_INTERFACE) {
313354
setEncrypted(false);
314355
}
315356
}
316357

358+
int UDisks2::Block::interfaceCount() const
359+
{
360+
return m_interfacePropertyMap.keys().count();
361+
}
362+
363+
bool UDisks2::Block::hasInterface(const QString &interface) const
364+
{
365+
return m_interfacePropertyMap.contains(interface);
366+
}
367+
317368
void UDisks2::Block::morph(const UDisks2::Block &other)
318369
{
319370
if (&other == this)
@@ -341,6 +392,12 @@ void UDisks2::Block::morph(const UDisks2::Block &other)
341392
qCWarning(lcMemoryCardLog) << "Failed to connect to Block properties change interface" << m_path << m_connection.lastError().message();
342393
}
343394

395+
qCInfo(lcMemoryCardLog) << "Morphing" << qPrintable(device()) << "that was" << (m_formatting ? "formatting" : "not formatting" ) << "to" << qPrintable(other.device());
396+
qCInfo(lcMemoryCardLog) << "Old block:";
397+
dumpInfo();
398+
qCInfo(lcMemoryCardLog) << "New block:";
399+
other.dumpInfo();
400+
344401
m_interfacePropertyMap = other.m_interfacePropertyMap;
345402
m_data = other.m_data;
346403
m_drive = other.m_drive;
@@ -351,6 +408,7 @@ void UDisks2::Block::morph(const UDisks2::Block &other)
351408
m_formatting = other.m_formatting;
352409
m_locking = other.m_locking;
353410

411+
354412
if (wasFormatting && hasCryptoBackingDevice()) {
355413
rescan(cryptoBackingDeviceObjectPath());
356414
}
@@ -370,19 +428,21 @@ void UDisks2::Block::updateProperties(const QDBusMessage &message)
370428
emit updated();
371429
}
372430
} else if (interface == UDISKS2_FILESYSTEM_INTERFACE) {
373-
updateMountPoint(arguments.value(1));
431+
updateFileSystemInterface(arguments.value(1));
374432
}
375433
}
376434

377435
bool UDisks2::Block::isCompleted() const
378436
{
379-
return !m_pendingFileSystem && !m_pendingBlock && !m_pendingEncrypted && !m_pendingDrive;
437+
return !m_pendingFileSystem && !m_pendingBlock && !m_pendingEncrypted && !m_pendingDrive
438+
&& !m_pendingPartition && !m_pendingPartitionTable;
380439
}
381440

382-
void UDisks2::Block::updateMountPoint(const QVariant &mountPoints)
441+
void UDisks2::Block::updateFileSystemInterface(const QVariant &filesystemInterface)
383442
{
384-
QVariantMap mountPointsMap = NemoDBus::demarshallArgument<QVariantMap>(mountPoints);
385-
QList<QByteArray> mountPointList = NemoDBus::demarshallArgument<QList<QByteArray> >(mountPointsMap.value(QStringLiteral("MountPoints")));
443+
QVariantMap filesystem = NemoDBus::demarshallArgument<QVariantMap>(filesystemInterface);
444+
m_interfacePropertyMap.insert(UDISKS2_FILESYSTEM_INTERFACE, filesystem);
445+
QList<QByteArray> mountPointList = NemoDBus::demarshallArgument<QList<QByteArray> >(filesystem.value(QStringLiteral("MountPoints")));
386446
m_mountPath.clear();
387447

388448
for (const QByteArray &bytes : mountPointList) {
@@ -402,7 +462,7 @@ void UDisks2::Block::updateMountPoint(const QVariant &mountPoints)
402462
emit updated();
403463
}
404464

405-
qCInfo(lcMemoryCardLog) << "New file system mount points:" << mountPoints << "resolved mount path: " << m_mountPath << "trigger update:" << triggerUpdate;
465+
qCInfo(lcMemoryCardLog) << "New file system mount points:" << filesystemInterface << "resolved mount path: " << m_mountPath << "trigger update:" << triggerUpdate;
406466
emit mountPathChanged();
407467
}
408468

@@ -421,79 +481,6 @@ bool UDisks2::Block::clearFormattingState()
421481
return false;
422482
}
423483

424-
void UDisks2::Block::getFileSystemInterface()
425-
{
426-
QDBusInterface dbusPropertyInterface(UDISKS2_SERVICE,
427-
m_path,
428-
DBUS_OBJECT_PROPERTIES_INTERFACE,
429-
m_connection);
430-
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_FILESYSTEM_INTERFACE);
431-
m_pendingFileSystem = new QDBusPendingCallWatcher(pendingCall, this);
432-
connect(m_pendingFileSystem, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
433-
if (watcher->isValid() && watcher->isFinished()) {
434-
QDBusPendingReply<> reply = *watcher;
435-
QDBusMessage message = reply.reply();
436-
updateMountPoint(message.arguments().at(0));
437-
} else {
438-
QDBusError error = watcher->error();
439-
qCWarning(lcMemoryCardLog) << "Error reading filesystem properties:" << error.name() << error.message() << m_path;
440-
m_mountable = false;
441-
}
442-
m_pendingFileSystem->deleteLater();
443-
m_pendingFileSystem = nullptr;
444-
complete();
445-
});
446-
}
447-
448-
void UDisks2::Block::getEncryptedInterface()
449-
{
450-
QDBusInterface dbusPropertyInterface(UDISKS2_SERVICE,
451-
m_path,
452-
DBUS_OBJECT_PROPERTIES_INTERFACE,
453-
m_connection);
454-
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_ENCRYPTED_INTERFACE);
455-
m_pendingEncrypted = new QDBusPendingCallWatcher(pendingCall, this);
456-
connect(m_pendingEncrypted, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
457-
if (watcher->isValid() && watcher->isFinished()) {
458-
m_encrypted = true;
459-
} else {
460-
QDBusError error = watcher->error();
461-
qCWarning(lcMemoryCardLog) << "Error reading encrypted properties:" << error.name() << error.message() << m_path;
462-
m_encrypted = false;
463-
}
464-
m_pendingEncrypted->deleteLater();
465-
m_pendingEncrypted = nullptr;
466-
complete();
467-
});
468-
}
469-
470-
void UDisks2::Block::getDriveProperties()
471-
{
472-
QDBusInterface drivePropertyInterface(UDISKS2_SERVICE,
473-
drive(),
474-
DBUS_OBJECT_PROPERTIES_INTERFACE,
475-
m_connection);
476-
QDBusPendingCall pendingCall = drivePropertyInterface.asyncCall(DBUS_GET_ALL, UDISKS2_DRIVE_INTERFACE);
477-
m_pendingDrive = new QDBusPendingCallWatcher(pendingCall, this);
478-
connect(m_pendingDrive, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
479-
if (watcher->isValid() && watcher->isFinished()) {
480-
QDBusPendingReply<> reply = *watcher;
481-
QDBusMessage message = reply.reply();
482-
QVariantMap driveProperties = NemoDBus::demarshallArgument<QVariantMap>(message.arguments().at(0));
483-
qCInfo(lcMemoryCardLog) << "Drive properties:" << driveProperties;
484-
m_drive = driveProperties;
485-
} else {
486-
QDBusError error = watcher->error();
487-
qCWarning(lcMemoryCardLog) << "Error reading drive properties:" << error.name() << error.message();
488-
m_drive.clear();
489-
}
490-
491-
m_pendingDrive->deleteLater();
492-
m_pendingDrive = nullptr;
493-
complete();
494-
});
495-
}
496-
497484
void UDisks2::Block::rescan(const QString &dbusObjectPath)
498485
{
499486
QVariantList arguments;
@@ -516,3 +503,35 @@ void UDisks2::Block::rescan(const QString &dbusObjectPath)
516503
watcher->deleteLater();
517504
});
518505
}
506+
507+
void UDisks2::Block::getProperties(const QString &path, const QString &interface,
508+
QPointer<QDBusPendingCallWatcher> &watcherPointer,
509+
std::function<void (const QVariantMap &)> success)
510+
{
511+
if (path.isEmpty() || path == QLatin1String("/")) {
512+
qCInfo(lcMemoryCardLog) << "Ignoring get properties from path:" << path << "interface:" << interface;
513+
return;
514+
}
515+
516+
QDBusInterface dbusPropertyInterface(UDISKS2_SERVICE,
517+
path,
518+
DBUS_OBJECT_PROPERTIES_INTERFACE,
519+
m_connection);
520+
QDBusPendingCall pendingCall = dbusPropertyInterface.asyncCall(DBUS_GET_ALL, interface);
521+
watcherPointer = new QDBusPendingCallWatcher(pendingCall, this);
522+
connect(watcherPointer.data(), &QDBusPendingCallWatcher::finished, this, [success, path, interface](QDBusPendingCallWatcher *watcher) {
523+
if (watcher->isValid() && watcher->isFinished()) {
524+
QDBusPendingReply<> reply = *watcher;
525+
QDBusMessage message = reply.reply();
526+
success(NemoDBus::demarshallArgument<QVariantMap>(message.arguments().at(0)));
527+
} else {
528+
qCDebug(lcMemoryCardLog) << "Get properties failed" << path << "interface:" << interface << watcher->isValid() << watcher->isFinished() << watcher->isError();
529+
QDBusPendingReply<> reply = *watcher;
530+
QDBusMessage message = reply.reply();
531+
QDBusError error = watcher->error();
532+
qCDebug(lcMemoryCardLog) << "Error reading" << message.interface() << "properties:" << error.name() << error.message();
533+
}
534+
535+
watcher->deleteLater();
536+
});
537+
}

0 commit comments

Comments
 (0)