412f1ad11e
Make GUnixMountMonitor thread-safe Resolves: RHEL-23636
229 lines
7.8 KiB
Diff
229 lines
7.8 KiB
Diff
From 71a5f1b6314dfe26037cc586025e1cd6e2e70ca6 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
Date: Mon, 22 Jan 2024 15:29:37 +0100
|
|
Subject: [PATCH 1/3] gunixmounts: Use libmnt_monitor API for monitoring
|
|
|
|
The `GUnixMountMonitor` object implements monitoring on its own currently.
|
|
Only the `/proc/mounts` file changes are monitored. It is not aware of the
|
|
`/run/mount/utab` file changes. This file contains the userspace mount
|
|
options (e.g. `x-gvfs-notrash`, `x-gvfs-hide`) among others. There is a
|
|
problem when `/sbin/mount.<type>` (e.g. `mount.nfs`) helper programs are
|
|
used. In that case, the `/run/mount/utab` file is updated later than the
|
|
`/proc/mounts` file and thus the `GUnixMountMonitor` clients (e.g.
|
|
`gvfs-udisks2-volume-monitor`, `gvfsd-trash`) don't see the userspace
|
|
options until the next `mount-changed` signal. Let's use the `libmnt_monitor`
|
|
API for monitoring instead and emit the `mount-changed` signal also when the
|
|
`/run/mount/utab` file is changed.
|
|
|
|
Related: https://issues.redhat.com/browse/RHEL-14607
|
|
Related: https://github.com/util-linux/util-linux/pull/2607
|
|
---
|
|
gio/gunixmounts.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 71 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
|
|
index 4695d5618..5d455ea0b 100644
|
|
--- a/gio/gunixmounts.c
|
|
+++ b/gio/gunixmounts.c
|
|
@@ -198,6 +198,11 @@ static GSource *proc_mounts_watch_source;
|
|
#define endmntent(f) fclose(f)
|
|
#endif
|
|
|
|
+#ifdef HAVE_LIBMOUNT
|
|
+/* Protected by proc_mounts_source lock */
|
|
+static struct libmnt_monitor *proc_mounts_monitor = NULL;
|
|
+#endif
|
|
+
|
|
static gboolean
|
|
is_in (const char *value, const char *set[])
|
|
{
|
|
@@ -1788,7 +1793,36 @@ proc_mounts_changed (GIOChannel *channel,
|
|
GIOCondition cond,
|
|
gpointer user_data)
|
|
{
|
|
+ gboolean has_changed = FALSE;
|
|
+
|
|
+#ifdef HAVE_LIBMOUNT
|
|
+ if (cond & G_IO_IN)
|
|
+ {
|
|
+ G_LOCK (proc_mounts_source);
|
|
+ if (proc_mounts_monitor != NULL)
|
|
+ {
|
|
+ int ret;
|
|
+
|
|
+ /* The mnt_monitor_next_change function needs to be used to avoid false-positives. */
|
|
+ ret = mnt_monitor_next_change (proc_mounts_monitor, NULL, NULL);
|
|
+ if (ret == 0)
|
|
+ {
|
|
+ has_changed = TRUE;
|
|
+ ret = mnt_monitor_event_cleanup (proc_mounts_monitor);
|
|
+ }
|
|
+
|
|
+ if (ret < 0)
|
|
+ g_debug ("mnt_monitor_next_change failed: %s", g_strerror (-ret));
|
|
+ }
|
|
+ G_UNLOCK (proc_mounts_source);
|
|
+ }
|
|
+
|
|
+#else
|
|
if (cond & G_IO_ERR)
|
|
+ has_changed = TRUE;
|
|
+#endif
|
|
+
|
|
+ if (has_changed)
|
|
{
|
|
G_LOCK (proc_mounts_source);
|
|
mount_poller_time = (guint64) g_get_monotonic_time ();
|
|
@@ -1853,6 +1887,10 @@ mount_monitor_stop (void)
|
|
g_source_destroy (proc_mounts_watch_source);
|
|
proc_mounts_watch_source = NULL;
|
|
}
|
|
+
|
|
+#ifdef HAVE_LIBMOUNT
|
|
+ g_clear_pointer (&proc_mounts_monitor, mnt_unref_monitor);
|
|
+#endif
|
|
G_UNLOCK (proc_mounts_source);
|
|
|
|
if (mtab_monitor)
|
|
@@ -1894,9 +1932,37 @@ mount_monitor_start (void)
|
|
*/
|
|
if (g_str_has_prefix (mtab_path, "/proc/"))
|
|
{
|
|
- GIOChannel *proc_mounts_channel;
|
|
+ GIOChannel *proc_mounts_channel = NULL;
|
|
GError *error = NULL;
|
|
+#ifdef HAVE_LIBMOUNT
|
|
+ int ret;
|
|
+
|
|
+ G_LOCK (proc_mounts_source);
|
|
+
|
|
+ proc_mounts_monitor = mnt_new_monitor ();
|
|
+ ret = mnt_monitor_enable_kernel (proc_mounts_monitor, TRUE);
|
|
+ if (ret < 0)
|
|
+ g_warning ("mnt_monitor_enable_kernel failed: %s", g_strerror (-ret));
|
|
+
|
|
+ ret = mnt_monitor_enable_userspace (proc_mounts_monitor, TRUE, NULL);
|
|
+ if (ret < 0)
|
|
+ g_warning ("mnt_monitor_enable_userspace failed: %s", g_strerror (-ret));
|
|
+
|
|
+ ret = mnt_monitor_get_fd (proc_mounts_monitor);
|
|
+ if (ret >= 0)
|
|
+ {
|
|
+ proc_mounts_channel = g_io_channel_unix_new (ret);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ g_set_error_literal (&error, G_IO_ERROR, g_io_error_from_errno (-ret),
|
|
+ g_strerror (-ret));
|
|
+ }
|
|
+
|
|
+ G_UNLOCK (proc_mounts_source);
|
|
+#else
|
|
proc_mounts_channel = g_io_channel_new_file (mtab_path, "r", &error);
|
|
+#endif
|
|
if (proc_mounts_channel == NULL)
|
|
{
|
|
g_warning ("Error creating IO channel for %s: %s (%s, %d)", mtab_path,
|
|
@@ -1907,7 +1973,11 @@ mount_monitor_start (void)
|
|
{
|
|
G_LOCK (proc_mounts_source);
|
|
|
|
+#ifdef HAVE_LIBMOUNT
|
|
+ proc_mounts_watch_source = g_io_create_watch (proc_mounts_channel, G_IO_IN);
|
|
+#else
|
|
proc_mounts_watch_source = g_io_create_watch (proc_mounts_channel, G_IO_ERR);
|
|
+#endif
|
|
mount_poller_time = (guint64) g_get_monotonic_time ();
|
|
g_source_set_callback (proc_mounts_watch_source,
|
|
(GSourceFunc) proc_mounts_changed,
|
|
--
|
|
2.43.0
|
|
|
|
|
|
From 5ee14937831eec7384bbe4a63a61aa8edfbc801d Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
Date: Wed, 31 Jan 2024 13:35:39 +0100
|
|
Subject: [PATCH 2/3] gunixmounts: Use mnt_monitor_veil_kernel option
|
|
|
|
The previous commit enabled the `/run/mount/utab` monitoring. The problem
|
|
is that the `mount-changed` signal can be emitted twice for one mount. One
|
|
for the `/proc/mounts` file change and another one for the `/run/media/utab`
|
|
file change. This is still not ideal because e.g. the `GMount` objects for
|
|
mounts with the `x-gvfs-hide` option are added and immediately removed.
|
|
Let's enable the `mnt_monitor_veil_kernel` option to avoid this.
|
|
|
|
Related: https://github.com/util-linux/util-linux/pull/2725
|
|
---
|
|
gio/gunixmounts.c | 6 ++++++
|
|
meson.build | 9 +++++++--
|
|
2 files changed, 13 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
|
|
index 5d455ea0b..b8f4608d6 100644
|
|
--- a/gio/gunixmounts.c
|
|
+++ b/gio/gunixmounts.c
|
|
@@ -1948,6 +1948,12 @@ mount_monitor_start (void)
|
|
if (ret < 0)
|
|
g_warning ("mnt_monitor_enable_userspace failed: %s", g_strerror (-ret));
|
|
|
|
+#ifdef HAVE_MNT_MONITOR_VEIL_KERNEL
|
|
+ ret = mnt_monitor_veil_kernel (proc_mounts_monitor, TRUE);
|
|
+ if (ret < 0)
|
|
+ g_warning ("mnt_monitor_veil_kernel failed: %s", g_strerror (-ret));
|
|
+#endif
|
|
+
|
|
ret = mnt_monitor_get_fd (proc_mounts_monitor);
|
|
if (ret >= 0)
|
|
{
|
|
diff --git a/meson.build b/meson.build
|
|
index eaf8d3900..7e98fd426 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -1592,8 +1592,13 @@ xgettext = find_program('xgettext', required : false)
|
|
# libmount is only used by gio, but we need to fetch the libs to generate the
|
|
# pkg-config file below
|
|
libmount_dep = []
|
|
-if host_system == 'linux' and get_option('libmount')
|
|
- libmount_dep = [dependency('mount', version : '>=2.23', required : true)]
|
|
+if host_system == 'linux'
|
|
+ libmount_dep = dependency('mount', version : '>=2.23', required : get_option('libmount'))
|
|
+ glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found())
|
|
+
|
|
+ if libmount_dep.found() and cc.has_function('mnt_monitor_veil_kernel', dependencies: libmount_dep)
|
|
+ glib_conf.set('HAVE_MNT_MONITOR_VEIL_KERNEL', 1)
|
|
+ endif
|
|
endif
|
|
|
|
# gnutls is used optionally by ghmac
|
|
--
|
|
2.43.0
|
|
|
|
|
|
From 84b74be1efd4877bc476f1209c701b1a744a299b Mon Sep 17 00:00:00 2001
|
|
From: Michael Catanzaro <mcatanzaro@redhat.com>
|
|
Date: Thu, 1 Feb 2024 19:17:43 -0600
|
|
Subject: [PATCH 3/3] Adjust meson.build for older syntax
|
|
|
|
This isn't technically correct because libmount could be found but
|
|
disabled, but that's OK. In RHEL, it's enabled.
|
|
---
|
|
meson.build | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/meson.build b/meson.build
|
|
index 7e98fd426..aeaa99143 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -1686,7 +1686,7 @@ endif
|
|
if use_system_pcre
|
|
glib_conf.set('PCRE_LIBS', '-lpcre')
|
|
endif
|
|
-if libmount_dep.length() != 0
|
|
+if libmount_dep.found()
|
|
glib_conf.set('LIBMOUNT_LIBS', '-lmount')
|
|
glib_conf.set('HAVE_LIBMOUNT', 1)
|
|
endif
|
|
--
|
|
2.43.0
|
|
|