Lock files on linux

Linux Lock Files

Often times, running processes on a Linux system need to coordinate their operations to prevent conflicts or race conditions. For example, two processes may need to safely access a shared resource or a cron job may need to verify that a previous instance has completed before running again. Processes generally use the concept of file locking to serialize their actions. Cooperating processes acquire a lock on a lock file to indicate that it is their turn to run or manipulate a shared resource. The contents of the lock file is irrelevant; they exist purely to indicate that a resource is occupied.

Linux systems offer two kinds of locks: exclusive, or write, locks and shared, or read, locks. These locks behave differently:

  • If a process holds an exclusive lock on a file, then no other process can acquire a lock, shared or exclusive, on that file.
  • If a process holds a shared lock on a file, then no other process can acquire an exclusive lock on that file.
  • Multiple processes can hold a shared lock on a file simultaneously.

These locks are advisory on Linux systems, meaning that all processes must agree to respect locks held by a process. There are no safeguards to prevent an uncooperative process from ignoring a lock.

A (forced?) analogy

A lock file can be thought of as a record player. While someone is putting on a record (obtaining an exclusive lock):

  • No one else in the room can listen to the music (obtain a shared lock).
  • No one else can pick out their own record to play (obtain an exclusive lock).

Similarly, when everyone is listening to the music:

  • Anyone else can listen to the music (obtain a shared lock), too.
  • Anyone wanting to put on a different record (obtain an exclusive lock) must wait for everyone else to finish listening, first.

Locking files with flock

One common way to lock a file on a Linux system is flock . The flock command can be used from the command line or within a shell script to obtain a lock on a file and will create the lock file if it doesn’t already exist, assuming the user has the appropriate permissions. Some possible flags for flock are below:

  • -x Acquire an exclusive lock on a file (the default)
  • -s Acquire a shared lock on a file
  • -n Fail by exiting with an exit code of 1 instead of waiting if a lock on a file is not available
  • -w seconds If a lock is not available, wait a specified number of seconds before exiting with an exit code of 1
  • -u Drop a lock. A lock is typically dropped when the lock file is closed, so this flag is generally only needed in special cases

Using flock in a shell script

The flock command can be used in a shell script as follows:

 1 #!/bin/bash 2 # exclusive_lock.sh 3 4 ( 5 flock -xn 200 6 trap 'rm /var/lock/lockfile' 0 7 RETVAL=$? 8 if [ $RETVAL -eq 1 ] ; then 9 echo $RETVAL 10 exit 1 11 else 12 echo "sleeping" 13 sleep 10 14 fi 15 ) 200>/var/lock/lockfile
 1 #!/bin/bash 2 # shared_lock.sh 3 4 ( 5 flock -sn 200 6 trap 'rm /var/lock/lockfile' 0 7 RETVAL=$? 8 if [ $RETVAL -eq 1 ] ; then 9 echo $RETVAL 10 exit 1 11 else 12 echo "sleeping" 13 sleep 10 14 fi 15 ) 200>/var/lock/lockfile

These two scripts are nearly identical: the first one attempts to acquire an exclusive lock while the second one attempts to acquire a shared lock. When used this way, flock takes a file descriptor: 200 in this example. The script attempts to obtain the lock in a non-blocking way, meaning that the script will exit immediately with an exit code of 1 if the lock is not available. It then opens /var/lock/lockfile and assigns the file descriptor 200 to it. The trap statement isn’t needed for acquiring the lock, but ensures that the lock file is removed upon successful completion of the code block.

Читайте также:  Convert tiff to jpg linux

These scripts also show the advisory nature of file locking on Linux systems. The script itself is responsible for checking the return value of the flock statement and handle it appropriately.

Example 1: Acquiring an exclusive lock

In three terminals, run exclusive_lock.sh in the first, exclusive_lock.sh again in the second, and shared_lock.sh in the third. The output should look similar to the following:

> ./exclusive_lock.sh > sleeping 

Here, the first run of exclusive_lock.sh acquired an exclusive lock on /var/lock/lockfile and executed its sleep statement. Since the lock was already taken, neither the second run of exclusive_lock.sh nor the run of shared_lock.sh were able to obtain the lock and exited with an exit code of 1.

Example 2: Acquiring a shared lock

In three terminals, run shared_lock.sh in the first, shared_lock.sh in the second, and exclusive_lock.sh in the third. The output should look like the following:

The first run of shared_lock.sh acquired a shared lock on /var/lock/lockfile . Since multiple shared locks can exist simultaneously, the second run of shared_lock.sh also obtained a lock. However, since an exclusive lock cannot be obtained while a shared lock exists, the run of exclusive_lock.sh exited with an exit code of 1.

Share on

Linux Lock Files was published on May 18, 2015 and last modified on May 19, 2015 .

You might also enjoy (View all posts)

Источник

How to Lock a Text File in Linux Using flock Command

Before we explore the techniques/approaches of locking a text file under a Linux operating system environment, we should first understand the logic behind Linux’s file locking mechanism.

Linux’s file locking mechanism restricts/controls file access among multiple processes. When a text file is successfully locked, only one process can access it on a specific time schedule.

Before proceeding with this article, please understand that file locking is very much different from file encryption or file access control where a passphrase or password is needed to control user access to your files.

When a file is locked under a Linux operating system environment, a mutual exclusion event is created where only a single process can access it at a time.

Problem Statement

The Linux operating system will automatically block any write action attempts directed to an open file being written on by another process. However, what if you want to revoke the read and/or write permissions already invoked by the first process that has your file open and in write mode? Is there a workaround to this problem?

Moreover, we might also want to lock our file so that no other process interferes or attempt to disrupt the write mode status already initiated. This article will walk us through a viable solution to lock a text file in Linux.

Читайте также:  Linux awk print columns

Sample Reference File

For this tutorial to be more engaging and worthwhile, we should have some reference text files. We will concentrate on the text files inside the following directory:

Sample Text Files

For instance, let us open the file output.txt and start writing on it.

Write Content to File

While this file is still open, let us try to open it from another command line tab.

You will get the following response:

File is being edited by root

The above screen capture relays the PID (133110) of the process of working on the text file with the option of opening the file while it is still in that process’s write mode.

By keying in Y from our keyboard, we will have opened this text file and handed it over to a different process with exclusive write mode access.

Open Text Files

Therefore, a file modification by user 1 will lead to the following prompt on user 2 while attempting to save the file.

File was modified

This instance is a perfect representation of two different users on the network working on a single file.

Lock a Text File Using Linux’s flock Utility

To solve this issue, we need the aid of Linux’s flock utility. Since the util-linux package hosts flock command, it should be available in almost all Linux OS distributions. This command manages specific file/directory locks via the Linux command line environment.

To lock a text file in Linux, we will reference the following syntax:

$ flock -x PATH_TO_FILE_TO_LOCK -c COMMAND

The -x option is for obtaining a write lock to the targeted file. Let us attempt to lock the sample output.txt text file. The -c option will enable us to pass a single Linux supported command e.g. cat command.

$ flock -x /home/dnyce/LinuxShellTips_Files/output.txt -c cat

The terminal instance above will remain active to signify that the text file has been locked.

If we open another terminal (while this terminal instance is still running) and execute another flock command on this same file, we should be denied access to it.

$ flock -w .007 /home/dnyce/LinuxShellTips_Files/output.txt -c echo; /bin/echo $? 1 

The -w option is used to relay the wait time of .007 seconds before a lock is placed on the text file. We then execute echo $? to output the exit status of this command.

An exit status of 0 implies that the command was executed successfully and an exit status of 1 implies the command could not be executed due to an error. In this case, the text file is under lock by another process.

To further confirm that the text file is under lock, we can use the lslocks commands to list all active local system locks.

List File Locks in Linux

As you can see, our file is present.

Unlocking a Text File in Linux

Canceling the initial flock command (Ctrl+c) or closing the text file should release the lock making it possible to successfully run the following command on the secondary terminal.

$ flock -w .007 /home/dnyce/LinuxShellTips_Files/output.txt -c echo; /bin/echo $?

Unlocking File in Linux

The exit status of 0 implies that the lock is no longer applicable to the text file.

We have learned how to lock a text file in Linux so that only one process can use it (write mode) at a time. The implementation of this article is particularly useful when different users on a network are accessing a single file.

More on flock command can be found on its man page.

Источник

Linux flock, how to «just» lock a file?

But flock says flock: bad number: myfilelock How can I just lock a file, and release it when I want, without having to execute a command in the flock? It is to be used like this:

getLock myfilelock LOCK_EX somecommands . getLock myfilelock LOCK_UN 

@Jite I don’t understand you. I don’t wan’t to lock a file from being modified, just want to get a lock on it so another process running in PHP that locks the same file, waits for it to be released.

Читайте также:  Определить дату создания файла линукс

Redesign your script to use flock for every instance that needs to be lock-protected. Otherwise just create your own lock files, it’s just regular files.

So flock works like: process 1 executes flock lockfile command_to_run , process 2 executes flock lockfile some_command . Now the second process will be held up until the first one finishes. Simple as that. No need to even care about the lockfile itself, flock handles that automagically.

flock locks file descriptors, not files. That’s important, because it means that you cannot lock a file you aren’t holding open for the duration of the lock.

FYI, the function keyword is gratuitously incompatible with POSIX sh, and adds no value whatsoever over the POSIX syntax for declaring functions. Also, why use namespaced global variables when you can just use locals? Also, NEVER NEVER NEVER NEVER delete lockfiles created with flock (unless you’re completely sure nobody could be trying to grab a lock at the same time — so on reboot is safe); this creates race conditions. Leave the unlocked files on-disk to ensure that if two programs try to concurrently grab the same released lock, they get the same inode.

1 Answer 1

exec 3>filename # open a file handle; this part will always succeed flock -x 3 # lock the file handle; this part will block 
exec 3>&- # close the file handle 

You can also do it the way the flock man page describes:

. in which case the file is automatically closed when the block exits. (A subshell can also be used here, via using ( ) rather than < >, but this should be a deliberate decision — as subshells have a performance penalty, and scope variable modifications and other state changes to themselves).

If you’re running a new enough version of bash, you don’t need to manage file descriptor numbers by hand:

# this requires a very new bash -- 4.2 or so. exec >filename # open filename, store FD number in lock_fd flock -x "$lock_fd" # pass that FD number to flock exec >&- # later: release the lock 

. now, for your function, we’re going to need associative arrays and automatic FD allocation (and, to allow the same file to be locked and unlocked from different paths, GNU readlink) — so this won’t work with older bash releases:

declare -A lock_fds=() # store FDs in an associative array getLock() < local file=$(readlink -f "$1") # declare locals; canonicalize name local op=$2 case $op in LOCK_UN) [[ $]] || return # if not locked, do nothing exec >&- # close the FD, releasing the lock unset lock_fds[$file] # . and clear the map entry. ;; LOCK_EX) [[ $ ]] && return # if already locked, do nothing local new_lock_fd # don't leak this variable exec >"$file" # open the file. flock -x "$new_lock_fd" # . lock the fd. lock_fds[$file]=$new_lock_fd # . and store the locked FD. ;; esac > 

If you’re on a platform where GNU readlink is unavailable, I’d suggest replacing the readlink -f call with realpath from sh-realpath by Michael Kropat (relying only on widely-available readlink functionality, not GNU extensions).

Источник

Оцените статью
Adblock
detector