Codeigniter: Problem with garbage collector in session file driver

Created on 10 Jan 2020  路  12Comments  路  Source: bcit-ci/CodeIgniter

When two process run garbage collector in same time there is a lots of errors because of unlinking non existing files.
unlink(/path/writable/ci_sessioncd16549628ebaf9d9d70ed71814429254b76b723): No such file or directory /path/system/libraries/Session/drivers/Session_files_driver.php 386 | Called: /link1 unlink(/path/writable/ci_sessiona64823e065b23325b50871eaafb840fcfc39060e): No such file or directory /path/system/libraries/Session/drivers/Session_files_driver.php 386 | Called: /link2
And there is a lot of similar logs. Time of execution of GC are same.
Run on CI 3.1.4 but same code is in 3.1.11.

Most helpful comment

If that's a reply to my last comment, the "last person's comments" I was referring to have apparently been deleted.

All 12 comments

OK, but why would you have multiple processes running the same garbage collector at the same time?

Best practice is to outsorce the GC task to a cronjob, but even with the old pseudo-randomly triggered online GC that's built into PHP, the chance of this race-condition happening should be close to non-existent.

I use build into PHP mechanism to run GC. Chance to run GC twice is as You point out minimal, but it's happened in my project few time in last week.

Well, if you do indeed have this happening multiple times per week, I can only conclude that your configured probability values are set too high.
Unless you find a bug in the GC code that propagates the issue, unfortunately there's nothing we can do about it. We can't prevent duplicative GC execution - it's simply outside of our control - and while annoying, a tiny amount of logged false-positive warnings is better than no warnings of potential problems.

We can check if file exists while trying to unlink it, but it will be not optimal solution. Other thing that can be done it's mute errors for unlink via @. What do You think about that solution?

Don't know why you would say that existence check is not an optimal solution - it's the only solution and we already do it.
As for error suppression ... that's literally what I was addressing at the end of my last comment:

a tiny amount of logged false-positive warnings is better than no warnings of potential problems.

Now we now that file was existing while readdir was called. While unlinking we do not check that. And between those two operations file can be deleted by concurrent process.

There's also an is_file() and filemtime() calls between readdir() and unlink(), which should both fail in case the file is deleted and therefore act as double-checks. In practice, the only operation between the last existence check and deletion is a simple $mtime > $ts comparison ...

I don't know how PHP works specify in this case, but maybe result are get from cache generated by readdir()?

I can't rule out caching-related issues, but am 99% sure that readdir() in particular doesn't cache (the docs don't mention it either). If you manage to find a bug, that's one thing, but please don't go down this guesswork route ... it's not productive.

Just ignore that last person's comments. Don't know why or where he came from, but he's blocked so no reason to try interacting with him.

Likely he is simply unaware of TOCTOU issues. It's hard to tell, but maybe he would have been satisfied with putting the unlink calls in a try/catch and ignoring errors caused by the desired file not being there.

If that's a reply to my last comment, the "last person's comments" I was referring to have apparently been deleted.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Struki84 picture Struki84  路  7Comments

olisaagbafor picture olisaagbafor  路  3Comments

erikk1986 picture erikk1986  路  3Comments

huehnerhose picture huehnerhose  路  6Comments

Tjoosten picture Tjoosten  路  6Comments