Description
On some systems, rename(2) returns EXDEV when the data directory is on a different filesystem than /var/tmp. In these cases, MoinMoin.util.rename() fails and nothing works right.
Steps to reproduce
Find a system where rename(2) returns EXDEV when renaming across filesystems.
Run MoinMoin with a data directory on a separate volume.
Access the wiki and watch the failures ([Errno 18] Invalid cross-device link using os.rename)
Component selection
MoinMoin.util.rename() (in filesys.py) calls os.rename() on non-NT systems (line 80).
Details
shutil.move() calls os.rename() on systems where it will work; otherwise it does a copy/remove. While this loses atomicity of the operation it is more guaranteed to work.
Change MoinMoin/util/filesys.py line 80 from:
os.rename(oldname, newname)
to:
shutil.move(oldname, newname)
MoinMoin Version |
1.5.5.a |
OS and Version |
Linux Nokia-N800-10 |
Python Version |
Python 2.5.0 |
Server Setup |
MoinMoin Desktop |
Server Details |
MoinMoin Desktop |
Language you are using the wiki in (set in the browser/UserPreferences) |
English |
Workaround
Fix above works as long as atomicity can be sacrificed.
Or just set TMPDIR environment var to the same filesystem as your wiki.
Discussion
Nice, unusual platform.
Please add a traceback or a list of all problematic places calling filesys.rename. We can't just replace os.rename with shutil.move because some upper level code needs the OSError that shutil.move would cover.
This problem occurs whenever the cached html page is being generated. filesys.rename is called to move the generated HTML into the page cache. This breaks the entire wiki (users can't even view the front page) when os.rename() fails with EXDEV.
A more complete patch would be to catch the EXDEV error and execute shutil.move() instead.
Traceback (actually, the generated error page) is in the attachments (EXDEVErrorTrace.html)
This is a bug ... MoinMoin should not attempt to rename files that cannot be renamed (which is often the case for temporary files). shutil.move needs to be changed not to catch all IOErrors but only EXDEV.
Plan
- Priority:
- Assigned to:
- Status: