Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#16082 closed Bug (fixed)

Directory creation race condition in FileSystemStorage

Reported by: Pi Delport Owned by: nobody
Component: File uploads/storage Version: dev
Severity: Normal Keywords: FileSystemStorage directory creation race condition
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

My company recently encountered the following problem on a production server:

Traceback (most recent call last):

[...]

 File "[...]", line 191, in process_view
   storage.save(path, File([...]))

 File "[...]/python2.6/site-packages/django/core/files/storage.py", line 47, in save
   name = self._save(name, content)

 File "[...]/python2.6/site-packages/django/core/files/storage.py", line 146, in _save
   os.makedirs(directory)

 File "[...]/python2.6/os.py", line 157, in makedirs
   mkdir(name, mode)

OSError: [Errno 17] File exists: '[MEDIA_ROOT]/avatars/foo'

I tracked this down to a race condition in FileSystemStorage._save. When there is enough load, two concurrent processes can attempt to create the same intermediate directory, causing the second one to fail entirely.

To handle this robustly, FileSystemStorage should catch the EEXIST from os.makedirs and continue normally: I implemented this along with some tests, in the attached patch.

Note: For comparison, Python 3.2 added a keyword argument to os.makedirs to do this: see Issue 9299: os.makedirs(): Add a keyword argument to suppress "File exists" exception.

Attachments (1)

django-file_storage-makedirs-race.patch (3.8 KB ) - added by Pi Delport 13 years ago.

Download all attachments as: .zip

Change History (7)

by Pi Delport, 13 years ago

comment:1 by Aymeric Augustin, 13 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Aymeric Augustin, 13 years ago

Triage Stage: AcceptedReady for checkin

The patch looks good and contains extensive tests. It applies cleanly and the test suite passes. The implementation doesn't add much overhead. It's a fix for an edge case, so it does not deserve a mention in the release notes.

comment:3 by Pi Delport, 13 years ago

Thank you. :)

comment:4 by Jannis Leidel, 13 years ago

Resolution: fixed
Status: newclosed

In [16280]:

Fixed #16082 -- Fixed race condition in the FileSystemStorage backend with regard to creating directories. Thanks, pjdelport.

comment:5 by Aymeric Augustin, 13 years ago

#16108 describes a similar race condition in the file removal code.

comment:6 by Jannis Leidel, 13 years ago

In [16287]:

Fixed #16108 -- Fixed another race condition in the FileSystemStorage backend with regard to deleting a file. Refs #16082, too. Thanks, Aymeric Augustin.

Note: See TracTickets for help on using tickets.
Back to Top