From: Nir Soffer <nsoffer(a)redhat.com>
Unlinking a lockfile is racy; another instance may have the same
lockfile open, waiting on the lock.
This is a possible failure mode:
1. Process 1 holds the lock.
2. Process 2 opens the lockfile and tries to acquire the lockfile.
3. Process 1 unlinks the lockfile and releases it.
4. Process 2 acquires the unlinked lockfile.
5. Process 3 creates a new lockfile acquires it.
So we may end with 2 processes, both thinking they are the only instance
running.
This issue may be fixed by checking the lockfile inode before and after
locking to detect deleted lockfile. But there is a simpler solution;
since we have exactly one lockfile, don't delete it.
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
src/lockfile.c | 10 ----------
src/lockfile.h | 1 -
src/main.c | 2 +-
3 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/src/lockfile.c b/src/lockfile.c
index 1839f56..5a2518e 100644
--- a/src/lockfile.c
+++ b/src/lockfile.c
@@ -101,13 +101,3 @@ int lockfile(const char *dir, const char *name, int uid, int gid)
close(fd);
return -1;
}
-
-void unlink_lockfile(int fd, const char *dir, const char *name)
-{
- char path[PATH_MAX];
-
- snprintf(path, PATH_MAX, "%s/%s", dir, name);
- unlink(path);
- close(fd);
-}
-
diff --git a/src/lockfile.h b/src/lockfile.h
index 57bbcec..b6835d5 100644
--- a/src/lockfile.h
+++ b/src/lockfile.h
@@ -10,6 +10,5 @@
#define __LOCKFILE_H__
int lockfile(const char *dir, const char *name, int uid, int gid);
-void unlink_lockfile(int fd, const char *dir, const char *name);
#endif
diff --git a/src/main.c b/src/main.c
index 5be949b..1f879b0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1721,7 +1721,7 @@ static int do_daemon(void)
out:
/* order reversed from setup so lockfile is last */
close_logging();
- unlink_lockfile(fd, run_dir, SANLK_LOCKFILE_NAME);
+ close(fd);
return rv;
}
--
2.9.5