home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!snorkelwacker.mit.edu!ai-lab!life.ai.mit.edu!friedman
- From: friedman@gnu.ai.mit.edu (Noah Friedman)
- Newsgroups: comp.unix.shell
- Subject: Re: stale lock removal
- Message-ID: <FRIEDMAN.92Jul30162914@nutrimat.gnu.ai.mit.edu>
- Date: 30 Jul 92 20:29:14 GMT
- References: <1992Jul29.161417.2473@ddsw1.mcs.com>
- Sender: news@ai.mit.edu
- Organization: Free Software Foundation, 675 Mass Ave. Cambridge, MA 02139
- Lines: 86
- In-reply-to: dattier@ddsw1.mcs.com's message of 29 Jul 92 16:14:17 GMT
- X-Disclaimer: The article, except for quotations, is public domain.
-
- In article <1992Jul29.161417.2473@ddsw1.mcs.com> dattier@ddsw1.mcs.com (David W. Tamkin) writes:
- >Say a process finds that another process has the lock and it's going to wait
- >a bit and then try again. How can it determine whether the process that has
- >the lock is actively using it or has stalled?
-
- Most programs simply don't. They'll wait forever (either by checking
- periodically, implementing some sort of semaphore, or whatever) until the
- lock goes away. After all, there are lots of reasons why a program may be
- wedged (not merely zombified). Perhaps in some circumstances you can use
- some empirical guestimates for how long a process can reasonably hold a
- lock, and then steal it if it takes longer than that. Depends entirely on
- the nature of the data and the programs, I suppose (and you may still be
- subject to nasty but unlikely race conditions).
-
- Emacs has an advisory locking mechanism similar to the one you described
- later in your article. The lockfile contains the process-ID of the emacs
- process locking the file. When emacs notices that a file has a lock, it
- checks to see if the other process still exists (using a kill 0 and looking
- at the resulting errno). This implementation fails miserably with
- NFS-mounted files, because they could easily be edited on remote machines.
- We've been thinking informally about a new locking mechanism, but no solid
- ideas have been proposed. My guess is that emacs 19 will use the same
- fairly brain-dead locking mechanism which was fine when everyone worked on
- a single vax without networked file systems, but is now obviously
- inadequate. *sigh*. Anyone who has ideas, please send them to me!
-
- >Potentially process A could find that process B had the lock and go into these
- >tests; B could end and process C could get the lock but not yet have created
- >the signature file by the time A tests for a signature file to find out which
- >process has the lock.
-
- You should never assume you have a lock until you have successfully
- negotiated whatever protocol is necessary to demonstrate you have it.
-
- >Finally, is there some good way simply to tell the age of a lock (if not one
- >made with /etc/link, at least one make with mknod p or with mkdir)? If a
- >lock is older than a certain age, one can figure that it is stale. Various
- >ls options will display last inode modification time or access time, but how
- >does one compare them to the current time efficiently?
- >
- >Any suggestions? This will have to be done with shell scripts or existing
- >utilities.
-
- I wrote the following for bash, though I admit I cheated by using perl
- to get at various system calls. :-)
-
- To use these, you basically just stat the file and get the mtime (or
- atime, whatever), and use "time2" to get the current system time. Then you
- can just do some simple arithmetic using expr or builtin bash routines to
- get the age of a file.
-
- Getting the age of locks that were acquired with lockd may be more
- difficult. :-)
-
-
- # dev ino mode nlink uid gid rdev size atime mtime ctime blksize blocks
- #
- # Converts mode to canonical 3-digit octal number (type bits can be gotten
- # with "test" anyway)
- function stat ()
- {
- perl - "$@" <<- '__EOF__'
- for ($i = 0; $i <= $#ARGV; $i += 1)
- {
- @st = stat("$ARGV[$i]");
- $st[2] = $st[2] & 0777;
- printf ("%ld %u %o %d %lu %lu %ld %lu %lu %lu %lu %lu %lu\n", @st);
- }
- __EOF__
- }
-
- # WARNING: In order to optimize computations after the first call to this
- # function, the `SECONDS' magic shell variable is used to compute changes
- # from the previous value. If this variable is ever assigned (or unset),
- # time2 will no longer provide the correct value.
- #:end docstring:
-
- function time2 ()
- {
- # Calling an external program is slow
- if [ "${_time_seconds+set}" != "set" ]; then
- _time_seconds=$(perl -e 'print(time());')
- fi
-
- echo $[ _time_seconds + SECONDS ]
- }
-