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 737022 - UI hangs while running libparted operations such as FAT16/FAT32 resizing
UI hangs while running libparted operations such as FAT16/FAT32 resizing
Status: RESOLVED FIXED
Product: gparted
Classification: Other
Component: application
0.15.0
Other Linux
: Normal normal
: ---
Assigned To: gparted maintainers alias
gparted maintainers alias
: 747131 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2014-09-20 13:12 UTC by Mike Fleetwood
Modified: 2015-08-03 17:32 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
libparted FS resize callback timing log (472.83 KB, text/plain)
2014-09-30 13:57 UTC, Mike Fleetwood
  Details
libparted FS resize callback timing debug 1 (10.14 KB, patch)
2014-09-30 13:58 UTC, Mike Fleetwood
none Details | Review
Fix FAT resize hangs GUI (v1) (4.15 KB, patch)
2015-07-14 19:49 UTC, Curtis Gedak
none Details | Review
Fix FAT resize hangs GUI (v2) (3.43 KB, patch)
2015-07-16 16:44 UTC, Curtis Gedak
none Details | Review
Fix FAT resize hangs GUI (v3) (3.45 KB, patch)
2015-07-16 19:01 UTC, Curtis Gedak
none Details | Review

Description Mike Fleetwood 2014-09-20 13:12:12 UTC
Since GParted commit 52a2a9b "Reduce threading (#685740)", released in
GPared 0.15.0, application of operations occurs in the main thread
running the UI, therefore long running libparted actions such as
resizing a FAT16 or FAT32 file system hang the UI for as long as it take
to complete the operation.
https://git.gnome.org/browse/gparted/commit/?id=52a2a9b00a32996921ace055e71d0e09fb33c5fe

This issue was discovered when testing bug #734718 - "Update Autoconf
version specific libparted checks and defines to feature specific ones"
https://bugzilla.gnome.org/show_bug.cgi?id=734718
in comments #1 to #5.
Comment 1 Mike Fleetwood 2014-09-20 13:17:43 UTC
Add Phillip Susi to the CC list
Comment 2 Phillip Susi 2014-09-29 14:35:01 UTC
Ahh yes, when calling the deprecated resize apis, gparted will need to take steps to avoid blocking the ui.  It can either register the timer callback function with the resize apis, which the resize code will invoke periodically to update the ui ( the function would need to drain the main loop of events, and then return ), or it can fork a thread to call the resize api in, and have the main thread wait for it in a nested main loop.
Comment 3 Mike Fleetwood 2014-09-30 13:57:21 UTC
Created attachment 287450 [details]
libparted FS resize callback timing log

Hi Phillip and Curtis,

Using libparted callbacks will make GParted much better but there will
still be some hangs in the UI.

My test case was:
 Create 10240 MiB FAT32 file system
 Create 5 GiB file using dd
 Copy linux GIT repo
 Delete 5 GiB file
 Resize in GParted to 5120 MiB

On my desktop with HDD the libparted file system resize step took
03m06s.

Libparted has timer callbacks in a few ped_file_system_*() functions of
which only ped_file_system_resize() is used by GParted.  From the timed
log I generated, there were 2 notable hangs:
1) ~9 seconds for ped_geometry_new()
2) ~42 seconds between last callback and ped_file_system_resize()
   returning.
This is much better than a 3 minute hang, but 42 seconds is still a long
time.

Thanks,
Mike
Comment 4 Mike Fleetwood 2014-09-30 13:58:27 UTC
Created attachment 287451 [details] [review]
libparted FS resize callback timing debug 1

Patchset used to produced the previous debugging
Comment 5 Phillip Susi 2014-09-30 14:23:13 UTC
Nice investigation!  Then yea, just go ahead and create a background thread to make the ped_file_system_xxx calls.
Comment 6 Mike Fleetwood 2015-04-01 07:44:48 UTC
*** Bug 747131 has been marked as a duplicate of this bug. ***
Comment 7 Chris Bainbridge 2015-04-01 10:19:59 UTC
Just a note from a duplicate bug, this is very confusing if the screen lock kicks in, since gparted then just appears as a blank grey window which the user is likely to interpret as a hang or crash.
Comment 8 Curtis Gedak 2015-07-14 19:49:51 UTC
Created attachment 307430 [details] [review]
Fix FAT resize hangs GUI (v1)

Thank you Mike, Phillip, and Chris for all your input on this issue.

When looking at the code I did not see a simple way to add threading to all libparted ped_file_system_xxx calls.  So I took a different tact and only added threading to the libparted ped_file_system_resize function call.  The addition of this one threading call appears to significantly reduce the UI unresponsiveness issue.

Note that I based my testing on Mike's steps in comment #3 (also outlined in the patch commit message).

I'm all ears if anyone has other suggestions on how to address this issue.
Comment 9 Mike Fleetwood 2015-07-15 21:37:50 UTC
Hi Curtis,

> I'm all ears if anyone has other suggestions on how to address this
> issue.

I remember when I was first looking into this issue that having back
something like the old code which created a separate thread to apply
each operation would fully insulate the GParted UI from any OS or
library call which takes long enough for a user to notice the UI wasn't
responding.  This assumes that the external command reading code and
updating the output into the UI is thread safe.  I think it might be.
Does mean that the threading for copy blocks becomes redundant.
Possibly for external command execution too, but I'm not sure if that is
still needed somewhere, such as in View > File System Support > Rescan
For Supported Actions.  This approach would take a lot more effort to
understand.

Your approach of just solving the known worst offender of
ped_file_system_resize() is simple to understand and test.


Will be a couple of days before I can review and test your code
properly.

Thanks,
Mike
Comment 10 Phillip Susi 2015-07-16 13:24:38 UTC
The patch looks great Curtis.  It is very clean and to the point.  The one issue I have with it is the fact that the background thread calls Gtk::Main::quit().  I can't remember why now, but when I was messing with threading before, I found I had to have the background thread post an idle event callback to the foreground and have that function call quit().  I thought it had something to do with the fact that each thread can have its own set of main loops, and so quit would quit the background thread's main loop, not the gui thread's.  Now that I glance at the gtk and glib code though, it appears it just maintains a single global list of main loops and quit always kills the most recent one, regardless of what thread it is in, which seems totally broken to me.  You might ask on the gtk mailing list about whether calling quit in a background thread is safe, or search it for an old discussion I think I had there the last time I messed with the threading in gparted.
Comment 11 Curtis Gedak 2015-07-16 16:44:25 UTC
Created attachment 307579 [details] [review]
Fix FAT resize hangs GUI (v2)

Thank you Mike and Phillip for your input.

Attached is an updated patch v2.  No code changes were made.  Instead
I removed the testing steps from the commit comment, and also added
that not only fat16/fat32 resizes are affected, but also hfs/hfs+.

For testing purposes the steps from the v1 commit message are listed
below:

1)  Create in GParted 10240 MiB FAT32 file system (/dev/sde2)

2)  Mount the file system (/mnt)
    # mount /dev/sde2 /mnt

3)  Create 5* GiB file using dd
    # dd if=/dev/zero of=/mnt/fiveGBfs.bin bs=1024 count=$((5*1024*1024))

    *Note that FAT32 supports maximum file size of 4 GiB only.

4)  Copy GIT repo (or simply lots of files)
    # git clone https://github.com/git/git.git /mnt/git

5)  Delete 5 GiB file
    # rm /mnt/fiveGBfs.bin

6)  Unmount the file system
    # umount /mnt

7)  Resize in GParted to 5120 MiB
    (Note responsiveness, or lack thereof, of GUI)


On the topic of thread safety, I believe that no other threads or
asynchronously spawned commands are running when the
ped_file_system_resize() function call is made in GParted_Core.  As
suggested by Phillip, I will search to see if I can find out more
regarding thread safety.  I will report back here with what I find.

As an aside, I tested growing a fat16 file system from 512 MiB to 8192
MiB and was correctly shown the libparted message regarding conversion
from fat16 to fat32.  To me this means that the libparted
ped_exception_handler() appears to be working with this newly added
thread.

Thanks,
Curtis
Comment 12 Curtis Gedak 2015-07-16 19:01:49 UTC
Created attachment 307583 [details] [review]
Fix FAT resize hangs GUI (v3)

As per Phillip's recommendation I created a new patch v3 that changes
one line
   FROM:
      Gtk::Main::quit();
   TO:
      g_idle_add( (GSourceFunc)_mainquit, NULL );

This aligns the thread_lp_ped_file_system_resize() code with the way
the set_devices_thread() works.

Patch v3 also includes the changes to the commit message as mentioned
in comment #11.


I don't claim to be an expert on threading.  And with the trouble
we've encountered with past changes to threading I think it prudent to
model new code after that which we know works.  Hence the change
Phillip recommended.  I also agree with Mike's observation that a
global change more akin to the original (prior to 0.15.0) threading is
more risky, so this smaller change has a reduced scope that should be
easier to understand and test.

For patch v3 in addition to successful resizing, and seeing prompt for
fat16 to fat32 conversion testing I also tested cancel functionality
with the following observations:

A) Without patch v1/2/3, it is impossible to invoke the cancel
   functionality because the GUI is frozen.  The GUI unfreezes when
   the ped_file_system_resize function call completes.

B) With patch v1/2/3, a user can choose Cancel, then Force Cancel,
   then Cancel Operation.  The GUI continues to be responsive; however
   the ped_file_system_resize thread continues to execute until it
   naturally finishes.  During this time the GUI button Force Cancel
   is greyed out.  At the end of the entire operation the file system
   is successfully resized, however the indication to cancel is shown
   in the gparted details.  This is not entirely correct, but I think
   is no worse than without the patch.

So both with and without patch v1/2/3 a user cannot actually cancel a
resize operation in the ped_file_system_resize function call.  The key
difference is that with the patch the GUI remains responsive.

In summary, I believe that patch v3 aligns with Phillips
recommendation and also permits the GUI to remain responsive while
resizing fat16/fat32/hfs/hfs+ file systems.

As always I am open to further suggestions.

Curtis
Comment 13 Phillip Susi 2015-07-17 01:20:00 UTC
Nice.. I was actually thinking that the message was a bit long and didn't need the testing steps.  FYI, you can use the git notes feature to add extra information like that and it will be displayed in the patch following a scissors line ( <----> ) so that reviewers can see it, but it won't be part of the commit message in the main repo when pushed.

Now if only I could remember why I decided before that it wasn't safe to call Gtk::Main::quit() from a background thread... will have to search the mailing list archives.
Comment 14 Mike Fleetwood 2015-07-19 12:04:48 UTC
Hi Curtis,

I've successfully tested resizing FAT16, FAT32, HFS and HFS+ across a
range of distros between CentOS 5 to Ubuntu 14.10.  As such I'm ready to
commit the change.

Do you mind if I make some white space layout changes to your patch?
To put commas immediately after parameters, rather than at the start of
the next parameter on the next line.
From this:
    function_name( parameter1
                 , parameter2
                 );
To this:
    function_name( parameter1,
                   parameter2 );
I'm trying to make the the GParted code use a more common layout style.

Thanks,
Mike
Comment 15 Curtis Gedak 2015-07-19 15:54:51 UTC
Hi Mike,

> Do you mind if I make some white space layout changes to your patch?

Sure, feel free to change the alignment.

There are many different coding styles, and I know that GParted contains several different ones.  I like when the parameters line up, so either coding style works for me.

Curtis
Comment 16 Mike Fleetwood 2015-07-19 21:02:43 UTC
This patch has now been pushed to the public GParted git repository:

Add libparted ped_file_system_resize thread to avoid blocking GUI (#737022)
https://git.gnome.org/browse/gparted/commit/?id=1561d1ae7ec1bdad5c378134fc4138f346615787

Thanks,
Mike
Comment 17 Curtis Gedak 2015-08-03 17:32:31 UTC
This enhancement was included in the GParted 0.23.0 release on August 3, 2015.