GIOLister: ignore system mounts as defined by GIO

Strawberry has some heuristics to exclude things
like the root mount, /boot, tmpfs, etc. from the devices list.

However, it's somewhat incomplete. GIO (GLib component)
has more complete definition of "internal system mounts"
that should not be presented to the user.

Additionally, don't try to query filesystems free/total size
if it's internal, as that triggers automounting for autofs
filesystems (#410).
This commit is contained in:
WGH 2022-01-09 22:35:46 +03:00 committed by Jonas Kvinge
parent b5cf83d501
commit a9aab0702c
5 changed files with 42 additions and 5 deletions

View File

@ -117,6 +117,9 @@ endif()
pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(GOBJECT REQUIRED gobject-2.0) pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
pkg_check_modules(GIO REQUIRED gio-2.0) pkg_check_modules(GIO REQUIRED gio-2.0)
if(UNIX)
pkg_check_modules(GIO_UNIX gio-unix-2.0)
endif()
pkg_check_modules(LIBCDIO libcdio) pkg_check_modules(LIBCDIO libcdio)
pkg_check_modules(GSTREAMER gstreamer-1.0) pkg_check_modules(GSTREAMER gstreamer-1.0)
pkg_check_modules(GSTREAMER_BASE gstreamer-base-1.0) pkg_check_modules(GSTREAMER_BASE gstreamer-base-1.0)
@ -391,6 +394,11 @@ optional_component(GIO ON "Devices: GIO device backend"
DEPENDS "Unix or Windows" "NOT APPLE" DEPENDS "Unix or Windows" "NOT APPLE"
) )
optional_component(GIO_UNIX ON "Devices: GIO device backend (Unix support)"
DEPENDS "libgio-unix" GIO_UNIX_FOUND
DEPENDS "Unix" "UNIX"
)
optional_component(LIBGPOD ON "Devices: iPod classic support" optional_component(LIBGPOD ON "Devices: iPod classic support"
DEPENDS "libgpod" LIBGPOD_FOUND DEPENDS "libgpod" LIBGPOD_FOUND
DEPENDS "gdk-pixbuf" GDK_PIXBUF_FOUND DEPENDS "gdk-pixbuf" GDK_PIXBUF_FOUND

View File

@ -986,6 +986,10 @@ if(HAVE_GIO)
link_directories(${GIO_LIBRARY_DIRS}) link_directories(${GIO_LIBRARY_DIRS})
endif() endif()
if(HAVE_GIO_UNIX)
link_directories(${GIO_UNIX_LIBRARY_DIRS})
endif()
if(HAVE_AUDIOCD) if(HAVE_AUDIOCD)
link_directories(${LIBCDIO_LIBRARY_DIRS}) link_directories(${LIBCDIO_LIBRARY_DIRS})
endif() endif()
@ -1113,6 +1117,11 @@ if(HAVE_GIO)
target_link_libraries(strawberry_lib PRIVATE ${GIO_LIBRARIES}) target_link_libraries(strawberry_lib PRIVATE ${GIO_LIBRARIES})
endif() endif()
if(HAVE_GIO_UNIX)
target_include_directories(strawberry_lib SYSTEM PRIVATE ${GIO_UNIX_INCLUDE_DIRS})
target_link_libraries(strawberry_lib PRIVATE ${GIO_UNIX_LIBRARIES})
endif()
if(HAVE_AUDIOCD) if(HAVE_AUDIOCD)
target_include_directories(strawberry_lib SYSTEM PRIVATE ${LIBCDIO_INCLUDE_DIRS}) target_include_directories(strawberry_lib SYSTEM PRIVATE ${LIBCDIO_INCLUDE_DIRS})
target_link_libraries(strawberry_lib PRIVATE ${LIBCDIO_LIBRARIES}) target_link_libraries(strawberry_lib PRIVATE ${LIBCDIO_LIBRARIES})

View File

@ -7,6 +7,7 @@
#cmakedefine HAVE_BACKTRACE #cmakedefine HAVE_BACKTRACE
#cmakedefine HAVE_GIO #cmakedefine HAVE_GIO
#cmakedefine HAVE_GIO_UNIX
#cmakedefine HAVE_DBUS #cmakedefine HAVE_DBUS
#cmakedefine HAVE_X11 #cmakedefine HAVE_X11
#cmakedefine HAVE_UDISKS2 #cmakedefine HAVE_UDISKS2

View File

@ -25,6 +25,9 @@
#include <glib.h> #include <glib.h>
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h> #include <gio/gio.h>
#ifdef HAVE_GIO_UNIX
# include <gio/gunixmounts.h>
#endif
#include <QtGlobal> #include <QtGlobal>
#include <QObject> #include <QObject>
@ -60,6 +63,8 @@ bool GioLister::DeviceInfo::is_suitable() const {
if (!volume_ptr) return false; // This excludes smb or ssh mounts if (!volume_ptr) return false; // This excludes smb or ssh mounts
if (is_system_internal) return false;
if (drive_ptr && !drive_removable) return false; // This excludes internal drives if (drive_ptr && !drive_removable) return false; // This excludes internal drives
if (filesystem_type.isEmpty()) return true; if (filesystem_type.isEmpty()) return true;
@ -447,7 +452,8 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) {
} }
g_object_unref(icon); g_object_unref(icon);
GFile *root = g_mount_get_root(mount); ScopedGObject<GFile> root;
root.reset_without_add(g_mount_get_root(mount));
// Get the mount path // Get the mount path
mount_path = ConvertAndFree(g_file_get_path(root)); mount_path = ConvertAndFree(g_file_get_path(root));
@ -466,6 +472,21 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) {
g_object_unref(actual_mount); g_object_unref(actual_mount);
} }
#ifdef HAVE_GIO_UNIX
GUnixMountEntry *unix_mount = g_unix_mount_for(g_file_get_path(root), NULL);
if (unix_mount) {
// the GIO's definition of system internal mounts include filesystems like
// autofs, tmpfs, sysfs, etc, and various system directories, including the root,
// /boot, /var, /home, etc.
is_system_internal = g_unix_mount_is_system_internal(unix_mount);
g_unix_mount_free(unix_mount);
// Although checking most of the internal mounts is safe,
// we really don't want to touch autofs filesystems, as that would
// trigger automounting.
if (is_system_internal) return;
}
#endif
// Query the filesystem info for size, free space, and type // Query the filesystem info for size, free space, and type
error = nullptr; error = nullptr;
GFileInfo *info = g_file_query_filesystem_info(root, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, nullptr, &error); GFileInfo *info = g_file_query_filesystem_info(root, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, nullptr, &error);
@ -494,9 +515,6 @@ void GioLister::DeviceInfo::ReadMountInfo(GMount *mount) {
g_object_unref(info); g_object_unref(info);
} }
} }
g_object_unref(root);
} }
void GioLister::DeviceInfo::ReadVolumeInfo(GVolume *volume) { void GioLister::DeviceInfo::ReadVolumeInfo(GVolume *volume) {

View File

@ -77,7 +77,7 @@ class GioLister : public DeviceLister {
private: private:
struct DeviceInfo { struct DeviceInfo {
DeviceInfo() : drive_removable(false), filesystem_size(0), filesystem_free(0), invalid_enclosing_mount(false) {} DeviceInfo() : drive_removable(false), filesystem_size(0), filesystem_free(0), invalid_enclosing_mount(false), is_system_internal(false) {}
QString unique_id() const; QString unique_id() const;
bool is_suitable() const; bool is_suitable() const;
@ -111,6 +111,7 @@ class GioLister : public DeviceLister {
QString filesystem_type; QString filesystem_type;
bool invalid_enclosing_mount; bool invalid_enclosing_mount;
bool is_system_internal;
}; };
void VolumeAdded(GVolume *volume); void VolumeAdded(GVolume *volume);