== A peculiar change in Linux _flock()_ and _fcntl()_ behavior Here is one of those fun issues that cause me to pull out my hair (although it can give me a peculiar sense of satisfaction to track it down). Suppose that you have two filenames, such as (not entirely hypothetically) _.vacation.dir_ and _.vacation.pag_. As it happens, these filenames are actually hardlinks, so there is only one actual file involved. Now, suppose you have code that is like this C-oid pseudo-code: > fl = {F_WRLCK, SEEK_SET, 0, 0, getpid()}; > > fd1 = open(".vacation.dir", O_RDONLY); > flock(fd1, LOCK_EX); > fd2 = open(".vacation.pag", O_RDWR); > fcntl(fd2, F_SETLK, &fl); If and only if you are on a sufficiently modern Linux *and* the files are on an NFS filesystem (possibly it depends on the NFS server), the _fcntl()_ will fail with ((EAGAIN)). If you don't know that the files are hardlinks, it may take you some time to realize what's going on, especially because many of the test programs you write will probably work fine (except when applied to that specific pair of files). (But wait, it gets weirder. Replace the _fcntl()_ with _flock()_ and it will fail even on local filesystems and on older kernels. {{ST:strike:This behavior disagrees with the manpage, which is explicit in that separate file descriptors to the same file are treated independently.}} ~~Updated~~: I was badly misreading the manpage and this is correct _flock()_ behavior; treating the file descriptors independently means that separate locks on them *will* conflict, not that they won't. See the comments.) In this case, Ubuntu 6.06 is not sufficiently modern but Ubuntu 8.04 is, and guess what we just did today. (If you guessed 'upgraded our mail server', you win.) Now, you might sensibly ask why we have code that is trying to do such a crazy thing in the first place. The answer to that is that the _fcntl()_ is actually done in the gdbm library's ((dbm_open)) function, which errors out if it fails. We don't want to error out, we just want to serialize things, and so we need to add our own locking to do so, which needs a file, and what better file to use than the other one of the DBM database files, since we know that it has to exist. (I am not sure what file to use as a replacement for the serialization, although clearly we need to find one.)