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