1LOCKFILE_CREATE(3)         Linux Programmer's Manual        LOCKFILE_CREATE(3)
2
3
4

NAME

6       lockfile_create, lockfile_remove, lockfile_touch, lockfile_check - man‐
7       age lockfiles
8

SYNOPSIS

10       #include <lockfile.h>
11
12       cc [ flag ... ] file ... -llockfile [ library ]
13
14       int lockfile_create( const char *lockfile, int retrycnt, int  flags  [,
15       struct lockargs args ] );
16       int lockfile_remove( const char *lockfile );
17       int lockfile_touch( const char *lockfile );
18       int lockfile_check( const char *lockfile, int flags  );
19

DESCRIPTION

21       Functions to handle lockfiles in an NFS safe way.
22
23   lockfile_create
24       The lockfile_create function creates a lockfile in an NFS safe way.
25
26       If  flags  is set to L_PID or L_PPID then lockfile_create will not only
27       check for an existing lockfile, but it will read the contents  as  well
28       to  see  if  it  contains a process id in ASCII. If so, the lockfile is
29       only valid if that process still exists.  Otherwise, a  lockfile  older
30       than 5 minutes is considered to be stale.
31
32       When  creating  a  lockfile, if L_PID is set in flags, then the current
33       process' PID will be written to the lockfile. Sometimes it can be  use‐
34       ful  to use the parent's PID instead (for example, the dotlockfile com‐
35       mand uses that). In such cases you can use the L_PPID flag instead.
36
37   lockfile_touch
38       If the lockfile is on a shared filesystem, it might have  been  created
39       by  a process on a remote host. So the L_PID or L_PPID method of decid‐
40       ing if a lockfile is still valid or stale is incorrect and must not  be
41       used.  If you are holding a lock longer than 5 minutes, a call to lock‐
42       file_create by another process will consider the lock stale and  remove
43       it.   To prevent this, call lockfile_touch to refresh the lockfile at a
44       regular interval (every minute or so).
45
46   lockfile_check
47       This function checks if a valid lockfile  is  already  present  without
48       trying to create a new lockfile.
49
50   lockfile_remove
51       Removes the lockfile.
52
53

RETURN VALUES

55       lockfile_create returns one of the following status codes:
56
57          #define L_SUCCESS   0    /* Lockfile created                      */
58          #define L_TMPLOCK   2    /* Error creating tmp lockfile           */
59          #define L_TMPWRITE  3    /* Can't write pid int tmp lockfile      */
60          #define L_MAXTRYS   4    /* Failed after max. number of attempts  */
61          #define L_ERROR     5    /* Unknown error; check errno            */
62          #define L_ORPHANED  7    /* Called with L_PPID but parent is gone */
63          #define L_RMSTALE   8    /* Failed to remove stale lockfile       */
64
65       lockfile_check returns 0 if a valid lockfile is present. If no lockfile
66       or no valid lockfile is present, -1 is returned.
67
68       lockfile_touch and lockfile_remove return 0 on success. On  failure  -1
69       is returned and errno is set appropriately. It is not an error to lock‐
70       file_remove() a non-existing lockfile.
71
72

ALGORITHM

74       The algorithm that is used to create a lockfile in an atomic way,  even
75       over NFS, is as follows:
76
77       1      A unique file is created. In printf format, the name of the file
78              is .lk%05d%x%s. The first argument (%05d) is the current process
79              id. The second argument (%x) consists of the 4 minor bits of the
80              value returned by time(2). The last argument is the system host‐
81              name.
82
83
84       2      Then  the lockfile is created using link(2). The return value of
85              link is ignored.
86
87
88       3      Now the lockfile is stat()ed. If the stat fails, we go  to  step
89              6.
90
91
92       4      The stat value of the lockfile is compared with that of the tem‐
93              porary file. If they are the same, we have the lock. The  tempo‐
94              rary  file  is deleted and a value of 0 (success) is returned to
95              the caller.
96
97
98       5      A check is made to see if the existing lockfile is a valid  one.
99              If it isn't valid, the stale lockfile is deleted.
100
101
102       6      Before  retrying,  we sleep for n seconds. n is initially 5 sec‐
103              onds, but after every retry 5 extra seconds is  added  up  to  a
104              maximum  of  60  seconds (an incremental backoff). Then we go to
105              step 2 up to retries times.
106

REMOTE FILE SYSTEMS AND THE KERNEL ATTRIBUTE CACHE

108       These functions do not lock a file - they generate a lockfile.  However
109       in  a  lot of cases, such as Unix mailboxes, all concerned programs ac‐
110       cessing the mailboxes agree on the fact that  the  presence  of  <file‐
111       name>.lock means that <filename> is locked.
112
113       If  you  are  using lockfile_create to create a lock on a file that re‐
114       sides on a remote server, and you already have that file open, you need
115       to  flush the NFS attribute cache after locking. This is needed to pre‐
116       vent the following scenario:
117
118       o  open /var/mail/USERNAME
119       o  attributes, such as size, inode, etc are now cached in the kernel!
120       o  meanwhile, another remote system appends data to /var/mail/USERNAME
121       o  grab lock using lockfile_create()
122       o  seek to end of file
123       o  write data
124
125       Now the end of the file really isn't the end of the file -  the  kernel
126       cached  the  attributes on open, and st_size is not the end of the file
127       anymore. So after locking the file, you need  to  tell  the  kernel  to
128       flush the NFS file attribute cache.
129
130       The  only  portable  way  to  do this is the POSIX fcntl() file locking
131       primitives - locking a file using fcntl() has the fortunate side-effect
132       of invalidating the NFS file attribute cache of the kernel.
133
134       lockfile_create()  cannot do this for you for two reasons. One, it just
135       creates a lockfile- it doesn't know which file you are actually  trying
136       to  lock! Two, even if it could deduce the file you're locking from the
137       filename, by just opening and closing it, it would invalidate  any  ex‐
138       isting  POSIX  locks  the program might already have on that file (yes,
139       POSIX locking semantics are insane!).
140
141       So basically what you need to do is something like this:
142
143         fd = open("/var/mail/USER");
144         .. program code ..
145
146         lockfile_create("/var/mail/USER.lock", x, y);
147
148         /* Invalidate NFS attribute cache using POSIX locks */
149         if (lockf(fd, F_TLOCK, 0) == 0) lockf(fd, F_ULOCK, 0);
150
151       You have to be careful with this if you're putting this in an  existing
152       program  that  might already be using fcntl(), flock() or lockf() lock‐
153       ing- you might invalidate existing locks.
154
155
156       There is also a non-portable way. A lot of NFS  operations  return  the
157       updated attributes - and the Linux kernel actually uses these to update
158       the attribute cache. One of these operations is chmod(2).
159
160       So stat()ing a file and then chmod()ing it to st.st_mode will not actu‐
161       ally change the file, nor will it interfere with any locks on the file,
162       but it will invalidate the attribute cache. The equivalent to use  from
163       a shell script would be
164
165         chmod u=u /var/mail/USER
166
167

PERMISSIONS

169       If  you  are  on  a system that has a mail spool directory that is only
170       writable by a special group (usually "mail") you cannot create a  lock‐
171       file directly in the mailspool directory without special permissions.
172
173       Lockfile_create  and  lockfile_remove  check  if  the  lockfile ends in
174       $USERNAME.lock, and if the directory the lockfile is writable by  group
175       "mail". If so, an external set group-id mail executable (dotlockfile(1)
176       ) is spawned to do the actual locking / unlocking.
177
178

FILES

180       /usr/lib/liblockfile.so.1
181
182

AUTHOR

184       Miquel van Smoorenburg
185
186

SEE ALSO

188       dotlockfile(1), maillock(3), touchlock (3), mailunlock(3)
189
190
191
192Linux Manpage                   27 Januari 2021             LOCKFILE_CREATE(3)
Impressum