0

I have a folder in Ubuntu Server, where users from different client machines (also Ubuntu) can edit the files (via FileZilla, but any other will do). However, when one user is editing one file, this file should be locked so others can't edit it at the same time. This should be the expected behavior (and it is, elsewhere). How to accomplish this in Ubuntu Server 14.04? Looks like an easy, even obvious task, but I just can't find it anywhere. Google only gives me "how to unlock a file locked by someone else".

EDIT

Following Lmwangi's suggestion, I'm trying to create a bash script to automate the task. First I used NFS to mount an image of the server folder on my client machine. Then I created the following script on the server folder:

flock -nx "$1" xdg-open "$1"

Still not able to test it.

Rodrigo
  • 65
  • 1
  • 9
  • There _may_ be something that can be done on the FTP server's side of things; which FTP server is being used? – Castaglia Jul 25 '16 at 17:47
  • You are missing the lock file to use. flock -nx /path/to/lockfile . I've updated my answer below with a nicer flock example. – Lmwangi Jul 27 '16 at 11:40
  • ah, I see you are using the file to read as the lock file too. It should work. Can you fuser/lsof the file? My output: ❯ lsof /tmp/a flock has fd field as: 3uW and vim has fd field as: 3u According to the lsof manual W is write lock on the entire file – Lmwangi Jul 27 '16 at 11:43

5 Answers5

2

FTP (filezilla) does not support locking. Perhaps if you set up NFS or SaMBa then used a normal file editor locking would work.

user9517
  • 114,104
  • 20
  • 206
  • 289
  • FileZilla also supports SFTP, but not sure if its the proper version... Thank you, I'll take a look at those options. – Rodrigo Jul 23 '16 at 00:25
  • 1
    Btw, "perhaps"? It's so strange that nobody seems to need locking remote files! Everybody uses Git these days? – Rodrigo Jul 25 '16 at 13:45
  • 1
    "If you want to lock a file in $HOME, forget about it as $HOME might be NFS and locks generally are not reliable there." and also "in one sentence: in its current state Linux file locking is unusable." (http://0pointer.de/blog/projects/locking.html) Not sure if that's still true (six years old), but is indeed disappointing. – Rodrigo Jul 25 '16 at 13:52
2

Depends on the mode of access to the files. For example,

  1. Shared resource being accessed by scripts/code: Share the mount via NFS, then use exclusive flock (man flock has an example) as a wrapper to your script. If you are writing a C/python/perl/... program, your environment should give your access to the flock syscall.
  2. Users are accessing files: This might be slightly tricky. If users are accessing the same files and clobber each other, it's upto the program they are using to detect multi user access. For example, vim would detect open files at an individual file level via the .swp system. If you can script the program launcher, perhaps wrapping it with a flock would help?

Flock help:

❯ flock -h

Usage:
 flock [-sxun][-w #] fd#
 flock [-sxon][-w #] file [-c] command...
 flock [-sxon][-w #] directory [-c] command...

Options:
 -s  --shared     Get a shared lock
 -x  --exclusive  Get an exclusive lock
 -u  --unlock     Remove a lock
 -n  --nonblock   Fail rather than wait
 -w  --timeout    Wait for a limited amount of time
 -o  --close      Close file descriptor before running command
 -c  --command    Run a single command string through the shell
 -h  --help       Display this text
 -V  --version    Display version

Example.

First subshell acquires a lock for 20 seconds and is pushed to the background. Any other process (the second one) fails immediately if the lock is acquired.

❯ (flock -nx /tmp/a sleep 20 && echo nice..)& flock -nx /tmp/a sleep 20 || echo  failed to lock                                                                                   ⏎
[1] 2546
failed to lock
❯ jobs
[1]  + running    ( flock -nx /tmp/a sleep 20 && echo nice..; )
❯ nice..

[1]  + 2546 done       ( flock -nx /tmp/a sleep 20 && echo nice..; )

--- Edit

# Flock using a lock file based on the md5 of the content. I'm being lazy here. I should md5 the filename... 
❯ open_something() { md5=$(md5sum /tmp/a | awk '{print $1}'); flock -nx /tmp/$md5 vim "$1" || echo "Oops. Go away" }                                               

# So now let's vim a file and background it immediately.
❯ open_something /tmp/a
[1]  + 9185 suspended  open_something /tmp/a
❯ jobs  
[1]  + suspended (signal)  open_something /tmp/a

# Let's see whether flock created a lock file based on the md5 of the file and who's using it...
❯ ls /tmp
vagrant  VMwareDnD  vmware-root  a  d41d8cd98f00b204e9800998ecf8427e  vgauthsvclog.txt.0
❯ fuser /tmp/d41d8cd98f00b204e9800998ecf8427e
/tmp/d41d8cd98f00b204e9800998ecf8427e:  9175  9176

# Another user/process tries to open the file
❯ open_something /tmp/a
Oops. Go away

# Let's kill the original vim process and another process can now acquire the lock.    
❯ fg
[1]  + 9185 continued  open_something /tmp/a

vagrant@ubuntu-trusty ~ ❯❯❯ open_something /tmp/a
Lmwangi
  • 342
  • 1
  • 6
2

should be locked ... the expected behavior ...

Your understanding of file locking semantics on Linux is incorrect. From the reference link given, you are basing your assumption on Windows file semantics. They dont apply on most unix based systems.

I couldn't find a hugely authoritative source but wikipedia however it is trivial to test.

https://en.wikipedia.org/wiki/File_locking#In_Unix-like_systems

Unix-like operating systems (including Linux and Apple's OS X) do not normally automatically lock open files or running programs.

(Wikipedia is actually wrong about running programs, so I edited it!)

On Linux, its normal operation to allow multiple writers and readers to operate on the same file at the same time.

The only time this is not true is when the file itself is an executable object that is currently loaded and you request write access.

File Locking is done as a non-mandatory option and is done via fcntl, flock or lockf which all the applications using the file must support and be using the same locking method for it to work.

Another method often employed is to create a new file which is a copy of the old file as a temporarily named file, then rename it over the top of the old file. This works as all renames are atomic on posix compatible filesystems -- people will see either the old file or the new file but not a mix of both.

If you want to achieve multiple writers editing the same file, you'll probably need to go with a method like git so users can push the changes to a change repository.

Or alternatively just use a Windows system which does the locking you understand if this feature is that critical to you.

Matthew Ife
  • 22,927
  • 2
  • 54
  • 71
  • Thank you for the detailed explanation. I don't want to use git, I think one person editing a file at a time (in the same room) is a reasonable and (supposedly) easier choice. I don't want to go back to Windows, either. I think that using fcntl, flock or lockf, or the renaming technique via bash script, will be the choice. – Rodrigo Jul 26 '16 at 13:50
0

Simply put, FTP does not support locking.

The reason is simple: when editing a file via FTP protocol, you really are not editing the server-side file itself, rather you edit a downloaded copy that is than re-uploaded with the same path/name of the original file.

On the other hand, protocols as NFS or SMB are block exchange protocols which enable direct editing by the client-side software.

In short: if you need locking, FTP is not the right tool.

shodanshok
  • 44,038
  • 6
  • 98
  • 162
0

No solution here, just a link to a more detailed explanation I found.

enter image description here