PROPOSAL: API for device locking library.
Hi,
here is a proposal for defining a library for locking devices.
I think that for this purpose, the use of a shared library is more
important than the algorithm used (unless it is broken ;-) as the goal
is the cooperation between programs running on one machine.
------- start of cut text --------------
A dynamically loadable library should be provided with the
Operating System for the purpose of locking devices.
The library should offer the following API:
pid_t is_dev_lock ( const char * devname);
pid_t lock_dev ( const char * devname);
pid_t relock_dev ( const char * devname, pid_t old_pid);
pid_t unlock_dev ( const char * devname, pid_t pid);
where devname is the full pathname of the device to be locked,
old_pid and pid are the ID of the process currently owning the
lock (ZERO desables the check of the owner).
Return value for success is ZERO (for is_dev_lock means that
there is no lock on that device), or the process ID of the owner
of the lock (which is never the current process).
Stale locks are always removed by any call to the library.
The implementation details are left intentionally undetailed, to
permit the development of methods more robust of the one
described in previous versions of the FHS.
The only constraint that is posed is that the library must
implement _also_ that method, to prevent conflicts with programs
directly using that method, when installed locally.
For this purpose, and only for this, here is reproduced the
text:
The naming convention which must be used is
"LCK.." followed by the base name of the device.
For example, to lock /dev/cua0 the file "LCK..cua0"
would be created.
The format used for device lock files must be the
HDB UUCP lock file format.
The HDB format is to store the process identifier
(PID) as a ten byte ASCII decimal number, with a
trailing newline.
For example, if process 1230 holds a lock file,
it would contain the eleven characters:
space, space, space, space, space, space, one,
two, three, zero, and newline.
Then, anything wishing to use /dev/cua0 can read
the lock file and act accordingly (all locks in
/var/lock should be world-readable).
A reference implementation of the library can be found at URL:
...
------- end ----------------------------
Issues like the name of the library and the name of the functions can be
discussed, I don't have a strong opinion on that.
I prepared such a library
(ftp://ftp.debian.org/debian/dists/unstable/main/source/libs/lockdev_0.*.tar.gz);
Here is the manpage:
------- start of cut text --------------
NAME
lockdev, liblockdev, is_dev_lock, lock_dev, relock_dev,
unlock_dev - manage device lockfiles
SYNOPSIS
#include <lockdev.h>
pid_t is_dev_lock( const char * devname);
pid_t lock_dev( const char * devname);
pid_t relock_dev( const char * devname, pid_t pid);
pid_t unlock_dev( const char * devname, pid_t pid);
cc [ flag ... ] file ... -llockdev [ library ]
DESCRIPTION
The lockdev functions act on device locks normally located
in /var/lock . The lock is acquired creating a pair of
files hardlinked between them and named after the device
name (as mandated by FSSTND) and the device's major and
minor numbers (as in SVr4 locks). This permits to circum
vent a problem using only the FSSTND lock method when the
same device exists under different names (for convenience
or when a device must be accessable by more than one group
of users).
The lock file names are typically in the form LCK..ttyS1
and LCK.004.065 , but is provided a way to easily modify
them to use the library on different architectures. The
content of those files is the pid of the process who owns
the lock.
The is_dev_lock() function simply checks if the device is
in some way locked and if the owner of the lock is still
active (otherways it removes the lock). It recognise a
valid lock even if only one of the two lock files exists
(and is owned by an existing process), thus permitting a
safe use of this library toghether with programs using
only FSSTND or SVr4 lock style.
The lock_dev() function first checks if the device is
already locked and then tryes to acquire the lock building
the two lock files. First it creates the file which name
contains the major and minor numbers (in SVr4 style), then
it creates the file with the device name in its name. This
order reduces the clashes with other processes trying to
lock the same device (even with a different name) and
using this library. It has no problem with processes that
uses only the FSSTND algorithm.
The relock_dev() function changes the owner of an existing
lock; if the pid of the old owner is provided, then it
checks if the lock was correctly assigned (otherways there
is the possibility of a process acquiring a lock which was
owned by another unrelated process). If the device was not
locked, locks it.
The unlock_dev() function removes the existing locks on
the device. If the pid of the owner of the lock is pro
vided, then it check if the locks are assigned to that
process, avoiding to remove locks assigned to other exist
ing processes.
RETURN VALUES
All the functions in lockdev library return ZERO on suc
cessfull completion of the function (is_dev_lock returns
zero if there is no lock on the device), otherways, if the
device is currently locked by an existing process, they
return the pid of the process owner of the lock. They
return a negative number when some kind of error happens.
Actually they all return only (-1).
FILES
/var/lock/LCK..<device>
/var/lock/LCK.<major>.<minor>
/usr/lib/liblockdev.so.0
/usr/lib/debug/liblockdev.so.0
HISTORY
(c) 1997 by Fabrizio Polacco <fpolacco@debian.org>.
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU Library Gen
eral Public License as published by the Free Software
Foundation; version 2 dated June, 1991.
------- end ----------------------------
Cheers,
fab
--
| fab@pukki.ntc.nokia.com fpolacco@prosa.it fpolacco@debian.org
| 6F7267F5 fingerprint 57 16 C4 ED C9 86 40 7B 1A 69 A1 66 EC FB D2 5E
| fabrizio.polacco@nokia.com gsm: +358 (0)40 707 2468
Reply to: