Blame SOURCES/daemon-Prevent-spawning-new-daemons-if-outgoing-oper.patch

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