6

When I try to upload a media file through the django admin interface, I get this error :

OSError: [Errno 45] Operation not supported

Here is the last line of the traceback :

  File "/path/to/home/Envs/myenv/lib/python3.5/site-packages/django/core/files/locks.py", line 112, in unlock
    ret = fcntl.lockf(_fd(f), fcntl.LOCK_UN)

I found this answer and one of the comments led me to this ticket and then to this commit, introduced in the ticket as a "workaround" (see below).

Here are the change I should do in django/core/files/locks.py according to the workaround.

  elif system_type == 'posix':
     def lock(file, flags):
-        fcntl.flock(fd(file), flags)
+        fcntl.lockf(fd(file), flags)

     def unlock(file):
-        fcntl.flock(fd(file), fcntl.LOCK_UN)
+        fcntl.lockf(fd(file), fcntl.LOCK_UN)

I tried to manually reverse the changes from this commit (replacing flock() calls with lockf() calls), but it I still get the same error. There also are patches, but these patches seem to old (~7 years old and I use django 1.9 with python 3.5).

How could I solve this?

EDIT :

As plombix mentioned, my home directory is mounted on a NFS.

EDIT2 :

I also tried to replace the flock calls with fcntl.fcntl() calls and I got a different error :

OSError: [Errno 14] Bad address
Community
  • 1
  • 1
vmonteco
  • 14,136
  • 15
  • 55
  • 86
  • 1
    dokterbob's branch [has this commit](https://github.com/dokterbob/django/commit/bbc5118190fc52e4386a530b03adf00ba7e4c306), from the comments on the issue, this simply allows passing a locking implementation. Now you need to find one that works for AFP mounts. – tutuDajuju Mar 24 '16 at 07:42

2 Answers2

2

You may want to specify that you are on a NFS file system ;P

lockf == flock UNSUPORTED by NFS

cf other post in stack "flock vs lockf"

If the semantics (behaviour over descriptor passing, forking, etc.) is acceptable, you should prefer lockf()/fcntl() locks over flock().

Locks in Linux, simply because the former works on NFS etc. filesystems, whereas the latter does not.

On BSDs and Mac OS X, I believe you need to explicitly use fcntl(), instead.

i suggest you redirect your operations over /temp or /goinfre/

Community
  • 1
  • 1
plombix
  • 396
  • 3
  • 13
0

I'm chipping in my unconfirmed solution with Django 2.0.5. By inspecting the locks.py in this version, it seems that if "File locking is not supported", the lock and unlock methods will be polyfilled with "Dummy functions that don't do anything".

But attempts to get a lock on NFS system do not fall into the except block to be polyfilled as such. So I manually patched the else block to be polyfilled as well.

def lock(f, flags):
    # ret = fcntl.flock(_fd(f), flags)
    # return ret == 0
    return False

def unlock(f):
    # ret = fcntl.flock(_fd(f), fcntl.LOCK_UN)
    # return ret == 0
    return True

This is not the best solution, of course. But Django managed to do a runserver on my local machine, for now.

user6616962
  • 101
  • 1
  • 2