Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!ukma!uflorida!novavax!twwells.com!bill From: bill@twwells.com (T. William Wells) Newsgroups: comp.unix.wizards Subject: Re: Locks for exclusive access to resources Message-ID: <1989Jun14.052648.20183@twwells.com> Date: 14 Jun 89 05:26:48 GMT References: <1020@twwells.uucp> Organization: None, Ft. Lauderdale, FL Lines: 69 Well, I have a number of responses to my question. > 1) Opening a lock file with O_EXCL. Not present in V7, so not portable. > 2) Using link, mknod, or mkdir to create the lock. (But > aren't there some systems where mkdir isn't atomic?) Mknod is not always available to the unprivileged (V7 again), and mkdir isn't atomic on a number of systems. Link seems to be the favorite. Chris Torek says that link can misbehave when using NFS: if the link request gets handled correctly but the reply to the requester gets lost, NFS will retry the request. If the server has forgotten that it succeeded in doing the link, it will retry the link, fail because the link is already there, and return the failure. The effect is that the link is created but the program thinks that it has not. (Is NFS really that dumb? Stateless doesn't have to mean mindless!) I see a way that this can be dealt with. Suppose that you first create a file whose name is constructed from your system name and pid. In an ideal world, that would be unique. Then do the link. If the link fails, check the number of links to your file. If it is 2, you can ignore the link failure. Does anyone see anything wrong with this? (Other than the problem with the system name?) > 3) Creating a file with permissions 000 (but this won't > necessarily work if one of the requestors' is root, right?) As I said, this doesn't work with root. I suppose that one could do a setuid and *then* do this; that means forking off a subprocess if one wants to remain root. Any reason that won't work? (Never mind that it is wasteful. I know that.) (And also: I know that 000 isn't necessary. Anything that forbids writing would do.) > 4) Using a server process to handle either the requests or the access. No one had much good to say about this; the comments boiled down to: "how"? Here's one way: I create a file from my machine name and pid. I wait till it goes away. When it does, I proceed. When I'm done, I create another file with some fixed name, just to let the server know that I'm done. To have the server perform the request, I would put the request data into the file and not exit till that file is deleted. (To tie up the pid.) Of course, this involves busy loops in both the user process and the server; I don't recommend it. I just thought I'd point out that it is possible to use this method, even with vanilla Unix. The following people contributed to the above: Chris Torek uunet!mimsy!chris Gordon Burditt gould!sun!Central!sneaky!gordon John F. Haugh II uunet!cs.utexas.edu!rpp386.Cactus.ORG!jfh Arndt Jonasson, uunet!mcvax!zyx.ZYX.SE!arndt, suggested a variation on the link method: instead of linking a file, *unlink* it. The idea that the default state is that the lock file exists. When you want the resource, you *un*link the lock file. If that succeeds, you go. If not, you fail. This should also have the same problem as the link solution: you can get back a failure when the unlink actually succeeds. I can't think of a reliable method of detecting this, however. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com