From dc6ef75333331cb2d6cfcfa4b2da49b3d5ad19ea Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Fri, 24 Mar 2023 15:33:54 +0100 Subject: [PATCH] udisks2: add support for 'safely removing storage' mountutils lacks implemention of ejecting storage on Linux. Add that to our own code (not to mountutils as it is hard to do DBus calls from there). --- debian/changelog | 3 ++- src/downloadthread.cpp | 7 +++++++ src/linux/udisks2api.cpp | 22 ++++++++++++++++++++++ src/linux/udisks2api.h | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index f0c4b30..6864775 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,9 @@ rpi-imager (1.7.4.1) unstable; urgency=medium * Advanced settings: fix creating files on FAT partition that are an exact multiple of cluster size. - * Do you want to apply saved settings window: offer no option, + * Do you want to apply saved settings window: offer 'no' option, without clearing settings. + * Eject storage properly on Linux. -- Floris Bos Fri, 24 Mar 2023 14:16:03 +0100 diff --git a/src/downloadthread.cpp b/src/downloadthread.cpp index f41f7d7..78d3678 100644 --- a/src/downloadthread.cpp +++ b/src/downloadthread.cpp @@ -775,7 +775,14 @@ void DownloadThread::_writeComplete() #endif if (_ejectEnabled) + { eject_disk(_filename.constData()); +#ifdef Q_OS_LINUX + /* mountutils only implemented unmount and not eject on Linux. Do so through udisks2 */ + UDisks2Api udisks; + udisks.ejectDrive(_filename); +#endif + } emit success(); } diff --git a/src/linux/udisks2api.cpp b/src/linux/udisks2api.cpp index 502d31f..52c2ced 100644 --- a/src/linux/udisks2api.cpp +++ b/src/linux/udisks2api.cpp @@ -244,6 +244,28 @@ void UDisks2Api::unmountDrive(const QString &device) _unmountDrive(devpath); } +void UDisks2Api::ejectDrive(const QString &device) +{ + QString devpath = _resolveDevice(device); + if (devpath.isEmpty()) + return; + + _unmountDrive(devpath); + ::sync(); + + QDBusInterface blockdevice("org.freedesktop.UDisks2", devpath, + "org.freedesktop.UDisks2.Block", QDBusConnection::systemBus()); + QString drivepath = blockdevice.property("Drive").value().path(); + if (!drivepath.isEmpty() && drivepath != "/") + { + QDBusInterface drive("org.freedesktop.UDisks2", drivepath, + "org.freedesktop.UDisks2.Drive", QDBusConnection::systemBus()); + QVariantMap ejectOptions; + qDebug() << "Ejecting drive: " << drive.property("Id").toString(); + drive.call("Eject", ejectOptions); + } +} + QByteArrayList UDisks2Api::mountPoints(const QString &partitionDevice) { QString devpath = _resolveDevice(partitionDevice); diff --git a/src/linux/udisks2api.h b/src/linux/udisks2api.h index 5cea40f..2fb52c1 100644 --- a/src/linux/udisks2api.h +++ b/src/linux/udisks2api.h @@ -17,6 +17,7 @@ class UDisks2Api : public QObject public: explicit UDisks2Api(QObject *parent = nullptr); int authOpen(const QString &device, const QString &mode = "rw"); + void ejectDrive(const QString &device); bool formatDrive(const QString &device, bool mountAfterwards = true); QString mountDevice(const QString &device); void unmountDrive(const QString &device);