Ticket #4147 (closed defect: fixed)

Opened 3 years ago

Last modified 3 years ago

mc hangs accessing files within a .tar.gz within a cpio within an rpm for first 60 seconds

Reported by: nvwarr Owned by: andrew_b
Priority: major Milestone: 4.8.26
Component: mc-vfs Version: 4.8.25
Keywords: Cc:
Blocked By: Blocking:
Branch state: merged Votes for changeset: committed-master

Description

In lib/vfs/gc.c in the function vfs_expire, curr_time and exp_time are declared guint64. curr_time is initialised with a timestamp and exp_time with this timestamp minus 60 seconds. Later there is if (stamping->time <= exp_time). Prior to commit a94dd7d2ded0dd3ce3f6cd2c56612327d065b5ac curr_time was initialised with a value larger than 60 seconds, so everything was fine. This commit changed the initialisation to a timer starting when mc is started. So for the first 60 seconds, the result of the subtraction is negative, but it is a guint64, so we just get a VERY large unsigned value and the if (stamping->time <= exp_time) is always true. So mc thinks the vfs hasn't been used recently and goes into an infinite loop.

If one opens a .rpm file with mc and goes into the CONTENTS.cpio and then tries to go into the .tar.gz there (this is the usual structure of a .rpm) after waiting 60 seconds, everything is fine. However, before 60 seconds, mc hangs. There may be other ways to trigger this, but this is how I discovered it.

The fix is to remove the subtraction of 60 seconds when initialising exp_time and add them to the left-hand side of the comparison.

Attachments

mc-fix-timer-unsigned-error.patch (801 bytes) - added by nvwarr 3 years ago.
Patch to fix the bug

Change History

Changed 3 years ago by nvwarr

Patch to fix the bug

comment:1 Changed 3 years ago by andrew_b

  • Version changed from master to 4.8.25
  • Component changed from mc-core to mc-vfs

comment:2 Changed 3 years ago by andrew_b

  • Owner set to andrew_b
  • Status changed from new to accepted

Remembering discussion #3859, I think it's time to drop mc_timer and use g_get_real_time(). There is no difference what time to use: relative to mc start moment or relative to UNIX epoch.

comment:3 Changed 3 years ago by andrew_b

  • Branch state changed from no branch to on review
  • Milestone changed from Future Releases to 4.8.26

Branch: 4147_vfs_timeout
Initial changeset:e612ea50a12c70dd1d636a3086c6889db52f9ce0

Please test.

comment:4 follow-up: ↓ 5 Changed 3 years ago by nvwarr

Branch 4147_vfs_timeout works for me. So that is another way to solve the problem. I still think that you should consider avoiding the subtraction of vfs_timeout seconds from an unsigned type, though. That's always a bit dangerous. I would consider that the real bug, which was exposed by using mc_timer and could potentially reoccur if a future change goes back to a relative time since startup of mc. That said, your fix does avoid the issue.

comment:5 in reply to: ↑ 4 Changed 3 years ago by andrew_b

Replying to nvwarr:

I still think that you should consider avoiding the subtraction of vfs_timeout seconds from an unsigned type, though.

guint64 is replaced with gint64 for all related variables and structure members.

That's always a bit dangerous. I would consider that the real bug, which was exposed by using mc_timer and could potentially reoccur if a future change goes back to a relative time since startup of mc.

mc_timer is removed in the 2nd commit in this branch.

comment:6 Changed 3 years ago by nvwarr

Oops, I missed the change to gint64. That's perfect then.

comment:7 Changed 3 years ago by andrew_b

  • Votes for changeset set to nvwarr andrew_b
  • Branch state changed from on review to approved

comment:8 Changed 3 years ago by andrew_b

  • Status changed from accepted to testing
  • Votes for changeset changed from nvwarr andrew_b to committed-master
  • Resolution set to fixed
  • Branch state changed from approved to merged

Merged to master: [446a031350d4da12f521cc37881bdaf016b33c1f].

git log --pretty=oneline f0a3794b0..446a03135

comment:9 Changed 3 years ago by andrew_b

  • Status changed from testing to closed
Note: See TracTickets for help on using tickets.