[lockdev-devel] [PATCH] locking of non-devices doesn't work with SVr4 lock files
Ludwig Nussel
ludwig.nussel at suse.de
Thu Mar 4 15:12:47 UTC 2010
---
src/lockdev.c | 98 ++++++++++++++++++++++++++++++++------------------------
1 files changed, 56 insertions(+), 42 deletions(-)
diff --git a/src/lockdev.c b/src/lockdev.c
index d4319ce..6a324f7 100644
--- a/src/lockdev.c
+++ b/src/lockdev.c
@@ -224,17 +224,21 @@ _dl_filename_1 (char *name,
const struct stat *st)
{
int l;
+ const char* xtra = "";
_debug( 3, "_dl_filename_1 (dev=%lx, rdev=%lx)\n",
(unsigned long)st->st_dev, (unsigned long)st->st_rdev);
/* lockfile of type /var/lock/LK.003.004.064 */
if(S_ISCHR(st->st_mode)) {
- l = sprintf( name, "%s/LK.%03u.%03u.%03u", LOCK_PATH,
- major(st->st_dev), major(st->st_rdev), minor(st->st_rdev));
+ } else if(S_ISBLK(st->st_mode)) {
+ /* block devices are not standardized */
+ xtra = "b.";
} else {
- /* no character device. There's no standard for that */
- l = sprintf( name, "%s/LK.x%03u.%03u.%03u", LOCK_PATH,
- (unsigned)(st->st_mode&S_IFMT)>>12, major(st->st_rdev), minor(st->st_rdev));
+ /* not a device at all, ie no major/minor number */
+ *name = 0;
+ return 0;
}
+ l = sprintf( name, "%s/LK.%s%03u.%03u.%03u", LOCK_PATH, xtra,
+ major(st->st_dev), major(st->st_rdev), minor(st->st_rdev));
_debug( 2, "_dl_filename_1 () -> len=%d, name=%s<\n", l, name);
return l;
}
@@ -570,12 +574,13 @@ dev_testlock(const char *devname)
* another program uses the FSSTND lock without the new one than
* the contrary; anyway we do both tests.
*/
- _dl_filename_1( lock, &statbuf);
- if ( (pid=_dl_check_lock( lock)) )
- close_n_return( pid);
- if ( pid_read ) {
- _dl_filename_0( lock, pid_read);
- _dl_check_lock( lock);
+ if (_dl_filename_1( lock, &statbuf)) {
+ if ( (pid=_dl_check_lock( lock)) )
+ close_n_return( pid);
+ if ( pid_read ) {
+ _dl_filename_0( lock, pid_read);
+ _dl_check_lock( lock);
+ }
}
@@ -662,22 +667,23 @@ dev_lock (const char *devname)
/* test the lock and try to lock; repeat untill an error or a
* lock happens
*/
- _dl_filename_1( lock1, &statbuf);
- while ( ! (pid=_dl_check_lock( lock1)) ) {
- if (( link( lock0, lock1) == -1 ) && ( errno != EEXIST )) {
- int rc = -errno;
+ if (_dl_filename_1( lock1, &statbuf)) {
+ while ( ! (pid=_dl_check_lock( lock1)) ) {
+ if (( link( lock0, lock1) == -1 ) && ( errno != EEXIST )) {
+ int rc = -errno;
+ unlink( lock0);
+ close_n_return(rc);
+ }
+ }
+ if ( pid != our_pid ) {
+ /* error or another one owns it now */
unlink( lock0);
- close_n_return(rc);
+ close_n_return( pid);
+ }
+ if ( pid_read ) { /* modifyed by _dl_check_lock() */
+ _dl_filename_0( lock, pid_read);
+ _dl_check_lock( lock); /* remove stale pid file */
}
- }
- if ( pid != our_pid ) {
- /* error or another one owns it now */
- unlink( lock0);
- close_n_return( pid);
- }
- if ( pid_read ) { /* modifyed by _dl_check_lock() */
- _dl_filename_0( lock, pid_read);
- _dl_check_lock( lock); /* remove stale pid file */
}
/* from this point lock1 is OUR! */
@@ -686,7 +692,7 @@ dev_lock (const char *devname)
if (( link( lock0, lock2) == -1 ) && ( errno != EEXIST )) {
int rc = -errno;
unlink( lock0);
- unlink( lock1);
+ if (*lock1) unlink( lock1);
close_n_return(rc);
}
}
@@ -697,7 +703,7 @@ dev_lock (const char *devname)
* We let them win.
*/
unlink( lock0);
- unlink( lock1);
+ if (*lock1) unlink( lock1);
close_n_return( pid);
}
/* quite unlike, but ... */
@@ -716,15 +722,19 @@ dev_lock (const char *devname)
* So simply check again for the lock should let us know if we
* were so much unlucky.
*/
- pid = _dl_check_lock( lock1);
pid2 = _dl_check_lock( lock2);
+ if (*lock1)
+ pid = _dl_check_lock( lock1);
+ else
+ pid = pid2;
+
if (( pid == pid2 ) && ( pid == our_pid )) {
_debug( 2, "dev_lock() got lock\n");
close_n_return( 0); /* locked by us */
}
/* oh, no! someone else stepped in! */
if ( pid == our_pid ) {
- unlink( lock1);
+ if (*lock1) unlink( lock1);
pid = 0;
}
if ( pid2 == our_pid ) {
@@ -797,10 +807,11 @@ dev_relock (const char *devname,
if ( pid && old_pid && pid != old_pid )
close_n_return( pid); /* error or locked by someone else */
- _dl_filename_1( lock1, &statbuf);
- pid = _dl_check_lock( lock1);
- if ( pid && old_pid && pid != old_pid )
- close_n_return( pid); /* error or locked by someone else */
+ if (_dl_filename_1( lock1, &statbuf)) {
+ pid = _dl_check_lock( lock1);
+ if ( pid && old_pid && pid != old_pid )
+ close_n_return( pid); /* error or locked by someone else */
+ }
if ( ! pid ) { /* not locked ??? */
/* go and lock it */
@@ -810,10 +821,12 @@ dev_relock (const char *devname,
/* we don't rewrite the pids in the lock files untill we're sure
* we own all the lockfiles
*/
- if ( ! (fd=fopen( lock1, "w")) )
- close_n_return( -errno); /* something strange */
- fprintf( fd, "%10d\n", (int)our_pid);
- fclose( fd);
+ if (*lock1) {
+ if ( ! (fd=fopen( lock1, "w")) )
+ close_n_return( -errno); /* something strange */
+ fprintf( fd, "%10d\n", (int)our_pid);
+ fclose( fd);
+ }
/* under normal conditions, this second file is a hardlink of
* the first, so we have yet modifyed it also, and this write
* seems redundant ... but ... doesn't hurt.
@@ -880,10 +893,11 @@ dev_unlock (const char *devname,
if ( pid && wpid && pid != wpid )
close_n_return( wpid); /* error or locked by someone else */
- _dl_filename_1( lock1, &statbuf);
- wpid = _dl_check_lock( lock1);
- if ( pid && wpid && pid != wpid )
- close_n_return( wpid); /* error or locked by someone else */
+ if (_dl_filename_1( lock1, &statbuf)) {
+ wpid = _dl_check_lock( lock1);
+ if ( pid && wpid && pid != wpid )
+ close_n_return( wpid); /* error or locked by someone else */
+ }
_dl_filename_0( lock0, wpid);
if ( wpid == _dl_check_lock( lock0))
@@ -893,7 +907,7 @@ dev_unlock (const char *devname,
* they have been built.
*/
unlink( lock2);
- unlink( lock1);
+ if (*lock1) unlink( lock1);
_debug( 2, "dev_unlock() unlocked\n");
close_n_return( 0); /* successfully unlocked */
}
--
1.6.4.2
More information about the lockdev-devel
mailing list