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       int lockfile_remove( const char *lockfile );
16       int lockfile_touch( const char *lockfile );
17       int lockfile_check( const char *lockfile, int flags  );
18

DESCRIPTION

20       The lockfile_create function creates a lockfile in an NFS safe way.
21
22       If flags is set to L_PID or L_PPID then lockfile_create will  not  only
23       check  for  an existing lockfile, but it will read the contents as well
24       to see if it contains a process id in ASCII. If  so,  the  lockfile  is
25       only valid if that process still exists.
26
27       When  creating  a  lockfile, if L_PID is set in flags, then the current
28       process' PID will be written to the lockfile. Sometimes it can be  use‐
29       ful  to use the parent's PID instead (for example, the dotlockfile com‐
30       mand uses that). In such cases you can use the L_PPID flag instead.
31
32       If the lockfile is on a shared filesystem, it might have  been  created
33       by  a process on a remote host. Thus the process-id checking is useless
34       and the L_PID flag should not be set. In this case, there  is  no  good
35       way  to  see if a lockfile is stale. Therefore if the lockfile is older
36       then 5 minutes, it will be removed.  That  is  why  the  lockfile_touch
37       function  is provided: while holding the lock, it needs to be refreshed
38       regulary (every minute or so) by calling lockfile_touch ()  .
39
40       The lockfile_check function checks  if  a  valid  lockfile  is  already
41       present without trying to create a new lockfile.
42
43       Finally the lockfile_remove function removes the lockfile.
44
45

RETURN VALUES

47       lockfile_create returns one of the following status codes:
48
49          #define L_SUCCESS   0    /* Lockfile created                      */
50          #define L_NAMELEN   1    /* Recipient name too long (> 13 chars)  */
51          #define L_TMPLOCK   2    /* Error creating tmp lockfile           */
52          #define L_TMPWRITE  3    /* Can't write pid int tmp lockfile      */
53          #define L_MAXTRYS   4    /* Failed after max. number of attempts  */
54          #define L_ERROR     5    /* Unknown error; check errno            */
55          #define L_ORPHANED  7    /* Called with L_PPID but parent is gone */
56
57       lockfile_check returns 0 if a valid lockfile is present. If no lockfile
58       or no valid lockfile is present, -1 is returned.
59
60       lockfile_touch and lockfile_remove return 0 on success. On  failure  -1
61       is returned and errno is set appropriately. It is not an error to lock‐
62       file_remove() a non-existing lockfile.
63
64

ALGORITHM

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

REMOTE FILE SYSTEMS AND THE KERNEL ATTRIBUTE CACHE

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

PERMISSIONS

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

FILES

173       /usr/lib/liblockfile.so.1
174
175

AUTHOR

177       Miquel van Smoorenburg <miquels@cistron.nl>
178
179

SEE ALSO

181       dotlockfile(1), maillock(3), touchlock (3), mailunlock(3)
182
183
184
185Linux Manpage                   05 Januari 2017             LOCKFILE_CREATE(3)
Impressum