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 then lockfile_create will not only  check  for
23       an  existing  lockfile, but it will read the contents as well to see if
24       it contains a process id in ASCII. If so, the lockfile is only valid if
25       that process still exists.
26
27       If  the  lockfile is on a shared filesystem, it might have been created
28       by a process on a remote host. Thus the process-id checking is  useless
29       and  the  L_PID  flag should not be set. In this case, there is no good
30       way to see if a lockfile is stale. Therefore if the lockfile  is  older
31       then  5  minutes,  it  will  be removed. That is why the lockfile_touch
32       function is provided: while holding the lock, it needs to be  refreshed
33       regulary (every minute or so) by calling lockfile_touch ()  .
34
35       The  lockfile_check  function  checks  if  a  valid lockfile is already
36       present without trying to create a new lockfile.
37
38       Finally the lockfile_remove function removes the lockfile.
39
40

RETURN VALUES

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

ALGORITHM

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

REMOTE FILE SYSTEMS AND THE KERNEL ATTRIBUTE CACHE

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

PERMISSIONS

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

FILES

167       /usr/lib/liblockfile.so.1
168
169

AUTHOR

171       Miquel van Smoorenburg <miquels@cistron.nl>
172
173

SEE ALSO

175       dotlockfile(1), maillock(3), touchlock (3), mailunlock(3)
176
177
178
179Linux Manpage                    04 June 2004               LOCKFILE_CREATE(3)
Impressum