OSerror when uploading files over a NFS

Viewed 649

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
2 Answers

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.

Related