You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.0 KiB
100 lines
3.0 KiB
From 396216f71abf6907efd1383ca0d1a597918cd83d Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
Date: Thu, 11 Oct 2018 17:47:59 +0200
|
|
Subject: [PATCH] daemon: Prevent spawning new daemons if outgoing operation
|
|
exists
|
|
|
|
A new daemon is always spawned if MountLocation method (or LookupMount for
|
|
automounted) is called and the respective mount isn't registered yet. This
|
|
is not usually an issue, because the redundant daemons are consequently
|
|
terminated. However, this is a problem if mount operations hang for some reason.
|
|
This may happen e.g. with trash backend due to stale NFS mounts. Consequently,
|
|
new and new daemons are spawned which may lead to system failures due to lack
|
|
of system resources. See the following downstream bug report:
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=1632960
|
|
|
|
Let's fix that behavior simply by preventing spawning of new daemons if
|
|
respective outgoing mount operations exist.
|
|
|
|
https://gitlab.gnome.org/GNOME/gvfs/merge_requests/19
|
|
---
|
|
daemon/mount.c | 26 ++++++++++++++++++++++++++
|
|
1 file changed, 26 insertions(+)
|
|
|
|
diff --git a/daemon/mount.c b/daemon/mount.c
|
|
index e242666d..33cae597 100644
|
|
--- a/daemon/mount.c
|
|
+++ b/daemon/mount.c
|
|
@@ -73,6 +73,7 @@ typedef void (*MountCallback) (VfsMountable *mountable,
|
|
|
|
static GList *mountables = NULL;
|
|
static GList *mounts = NULL;
|
|
+static GList *ongoing = NULL;
|
|
|
|
static gboolean fuse_available;
|
|
|
|
@@ -253,6 +254,7 @@ typedef struct {
|
|
char *obj_path;
|
|
gboolean spawned;
|
|
GVfsDBusSpawner *spawner;
|
|
+ GList *pending; /* MountData */
|
|
} MountData;
|
|
|
|
static void spawn_mount (MountData *data);
|
|
@@ -264,6 +266,7 @@ mount_data_free (MountData *data)
|
|
g_mount_spec_unref (data->mount_spec);
|
|
g_free (data->obj_path);
|
|
g_clear_object (&data->spawner);
|
|
+ g_list_free_full (data->pending, (GDestroyNotify) mount_data_free);
|
|
|
|
g_free (data);
|
|
}
|
|
@@ -271,7 +274,17 @@ mount_data_free (MountData *data)
|
|
static void
|
|
mount_finish (MountData *data, GError *error)
|
|
{
|
|
+ GList *l;
|
|
+
|
|
+ ongoing = g_list_remove (ongoing, data);
|
|
+
|
|
data->callback (data->mountable, error, data->user_data);
|
|
+ for (l = data->pending; l != NULL; l = l->next)
|
|
+ {
|
|
+ MountData *pending_data = l->data;
|
|
+ pending_data->callback (pending_data->mountable, error, pending_data->user_data);
|
|
+ }
|
|
+
|
|
mount_data_free (data);
|
|
}
|
|
|
|
@@ -493,6 +506,7 @@ mountable_mount (VfsMountable *mountable,
|
|
gpointer user_data)
|
|
{
|
|
MountData *data;
|
|
+ GList *l;
|
|
|
|
data = g_new0 (MountData, 1);
|
|
data->automount = automount;
|
|
@@ -502,6 +516,18 @@ mountable_mount (VfsMountable *mountable,
|
|
data->callback = callback;
|
|
data->user_data = user_data;
|
|
|
|
+ for (l = ongoing; l != NULL; l = l->next)
|
|
+ {
|
|
+ MountData *ongoing_data = l->data;
|
|
+ if (g_mount_spec_equal (ongoing_data->mount_spec, mount_spec))
|
|
+ {
|
|
+ ongoing_data->pending = g_list_append (ongoing_data->pending, data);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ongoing = g_list_append (ongoing, data);
|
|
+
|
|
if (mountable->dbus_name == NULL)
|
|
spawn_mount (data);
|
|
else
|
|
--
|
|
2.20.1
|
|
|