After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 739575 - backend crashed with SIGABRT when locked mutex is cleared
backend crashed with SIGABRT when locked mutex is cleared
Status: RESOLVED FIXED
Product: gvfs
Classification: Core
Component: mtp backend
git master
Other Linux
: Normal normal
: ---
Assigned To: Philip Langdale
gvfs-maint
Depends on:
Blocks:
 
 
Reported: 2014-11-03 16:39 UTC by Ondrej Holy
Modified: 2014-11-06 10:46 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
mtp: do not crash when device is unplugged (1.74 KB, patch)
2014-11-03 18:23 UTC, Ondrej Holy
committed Details | Review
mtp: avoid crash when backend is force unmounted (1.01 KB, patch)
2014-11-04 12:38 UTC, Ondrej Holy
committed Details | Review

Description Ondrej Holy 2014-11-03 16:39:40 UTC
g_mutex_clear in g_vfs_backend_mtp_finalize causes SIGABRT after g_vfs_backend_unmount_force is called and there is already running job (with locked mutex). 

See:
https://bugzilla.redhat.com/show_bug.cgi?id=1159610
Comment 1 Ondrej Holy 2014-11-03 16:48:24 UTC
Hard to say how to fix it gracefully, maybe we should just leak it for the case of force unmount to avoid those crashes...

Philip what are you thinking about?
Comment 2 Philip Langdale 2014-11-03 17:58:58 UTC
Just to capture the discussion:

1) The problem is that there's an outstanding job running at the time the plug is pulled.

2) This triggers the forced unmount, which asynchronously requests the backend be terminated.

3) The job continues to hang around, probably making no forward progress

4) The backend termination reaches the finalize call while the job still hold the mutex.

5) Boom.

I agree with Ondrej that there's no clean way to avoid this, except to leak the mutex in finalize - which is fine in practice.
Comment 3 Ondrej Holy 2014-11-03 18:23:10 UTC
Created attachment 289926 [details] [review]
mtp: do not crash when device is unplugged
Comment 4 Philip Langdale 2014-11-03 19:02:56 UTC
Comment on attachment 289926 [details] [review]
mtp: do not crash when device is unplugged

Thanks!
Comment 5 Ross Lagerwall 2014-11-03 21:13:11 UTC
It's also possible that a backend is force unmounted by the user.

In that case, I suppose the unmount method would hang trying to lock the mutex... but I'm not sure if the finalize method would still run eventually when (if) the backend exits.
Comment 6 Ondrej Holy 2014-11-04 12:38:26 UTC
Created attachment 289974 [details] [review]
mtp: avoid crash when backend is force unmounted

This could probably happens, because mtp backend doesn't limit number of threads, however I'm unable to reproduce it currently. But attached patch should fix it I hope... 

Mtp backend doesn't limit number of threads, however all methods are executed with locked mutex thus multiple threads isn't needed. Do not waste resources and limit maximal number of threads to one. This change should also avoid executing finalize with locked mutex (which leads to crash) when backend is force unmounted by user.
Comment 7 Ondrej Holy 2014-11-04 12:45:24 UTC
Comment on attachment 289926 [details] [review]
mtp: do not crash when device is unplugged

commit 37727a10ee377d5675413c9d72fee4b9273c60b2
Comment 8 Ondrej Holy 2014-11-04 12:47:21 UTC
Comment on attachment 289926 [details] [review]
mtp: do not crash when device is unplugged

Also pushed for gnome-3-14:
commit b34875f78f7cb314197e1deef85b426eb89e2bbe
Comment 9 Ondrej Holy 2014-11-04 13:33:43 UTC
So I've made some more testing. Finalize method is called after unmount method is finished and unmount method is executed last one thanks to the mutexes (and blocking new jobs when mount operation started), so the second patch isn't needed, however it could be useful from other reasons (e.g. wasting resources)...
Comment 10 Philip Langdale 2014-11-04 18:08:57 UTC
Review of attachment 289974 [details] [review]:

Seems reasonable to do as it reflects reality. I'd have done it to begin with if I knew it was a setting :-)
Comment 11 Ross Lagerwall 2014-11-04 18:28:46 UTC
Review of attachment 289974 [details] [review]:

If you do this, then you may as well save some more resources and remove the mutex, the unmount_started flag, and the recently added force_unmounted flag since all methods execute sequentially.
Comment 12 Ondrej Holy 2014-11-05 08:59:28 UTC
MAX_JOB_THREADS affects only maximal number of threads in a thread pool with jobs. So only jobs are executed sequentially. 

I don't think we can remove the unmount_started flag and the mutex, because check_event is running in a separate thread, see:

GThread *event_thread = g_thread_new ("events", check_event, event_ref);

I don't think we can remove the recently added force_unmounted flag either, because on_uevent is also called on thread and finalize could be executed before current job is finished...
Comment 13 Ross Lagerwall 2014-11-05 22:12:05 UTC
(In reply to comment #12)
> MAX_JOB_THREADS affects only maximal number of threads in a thread pool with
> jobs. So only jobs are executed sequentially. 
> 
> I don't think we can remove the unmount_started flag and the mutex, because
> check_event is running in a separate thread, see:
> 
> GThread *event_thread = g_thread_new ("events", check_event, event_ref);

Ah, I hadn't seen this extra thread.

> 
> I don't think we can remove the recently added force_unmounted flag either,
> because on_uevent is also called on thread and finalize could be executed
> before current job is finished...

Yeah, I suppose on_uevent is executed from the daemon's main main loop which could run in parallel with a job.

Go ahead and commit it :-)
Comment 14 Ondrej Holy 2014-11-06 10:46:04 UTC
Comment on attachment 289974 [details] [review]
mtp: avoid crash when backend is force unmounted

Committed to master with modified commit message...

commit 14032ee48bab618e9e7c75134f1c653e996bc4dd
Comment 15 Ondrej Holy 2014-11-06 10:46:58 UTC
Thanks for cooperation to fix this bug :-)