summaryrefslogtreecommitdiffstats
path: root/libdm/libdm-file.c
diff options
context:
space:
mode:
authorFabio M. Di Nitto <fdinitto@redhat.com>2010-07-13 13:51:01 +0000
committerFabio M. Di Nitto <fdinitto@redhat.com>2010-07-13 13:51:01 +0000
commit8c4e8a185a371ee6133168603890bfa923163f88 (patch)
tree0200fb53a4edf74f7ec6a9ee6dd2c12b29df8aa7 /libdm/libdm-file.c
parent8e3da446f4d81f693ead821db6cf1ca837ab19fc (diff)
downloadlvm2-8c4e8a185a371ee6133168603890bfa923163f88.tar.gz
lvm2-8c4e8a185a371ee6133168603890bfa923163f88.tar.xz
lvm2-8c4e8a185a371ee6133168603890bfa923163f88.zip
Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
Switch dmeventd to use dm_create_lockfile and drop duplicate code. Allow clvmd pidfile to be configurable. Switch cmirrord and clvmd to use dm_create_lockfile.
Diffstat (limited to 'libdm/libdm-file.c')
-rw-r--r--libdm/libdm-file.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/libdm/libdm-file.c b/libdm/libdm-file.c
index 749ee4f6..ae2da76d 100644
--- a/libdm/libdm-file.c
+++ b/libdm/libdm-file.c
@@ -84,3 +84,85 @@ int dm_fclose(FILE *stream)
return prev_fail || fclose_fail ? EOF : 0;
}
+
+int dm_create_lockfile(const char *lockfile)
+{
+ int fd, value;
+ size_t bufferlen;
+ ssize_t write_out;
+ struct flock lock;
+ char buffer[50];
+
+ if((fd = open(lockfile, O_CREAT | O_WRONLY,
+ (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
+ log_error("Cannot open lockfile [%s], error was [%s]",
+ lockfile, strerror(errno));
+ return 0;
+ }
+
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+ if (fcntl(fd, F_SETLK, &lock) < 0) {
+ if (errno != EACCES && errno != EAGAIN)
+ log_error("Cannot lock lockfile [%s], error was [%s]",
+ lockfile, strerror(errno));
+ else
+ log_error("process is already running");
+
+ goto fail;
+ }
+
+ if (ftruncate(fd, 0) < 0) {
+ log_error("Cannot truncate pidfile [%s], error was [%s]",
+ lockfile, strerror(errno));
+
+ goto fail;
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+ snprintf(buffer, sizeof(buffer)-1, "%u\n", getpid());
+
+ bufferlen = strlen(buffer);
+ write_out = write(fd, buffer, bufferlen);
+
+ if ((write_out < 0) || (write_out == 0 && errno)) {
+ log_error("Cannot write pid to pidfile [%s], error was [%s]",
+ lockfile, strerror(errno));
+
+ goto fail;
+ }
+
+ if ((write_out == 0) || (write_out < bufferlen)) {
+ log_error("Cannot write pid to pidfile [%s], shortwrite of"
+ "[%" PRIsize_t "] bytes, expected [%" PRIsize_t "]\n",
+ lockfile, write_out, bufferlen);
+
+ goto fail;
+ }
+
+ if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
+ log_error("Cannot get close-on-exec flag from pidfile [%s], "
+ "error was [%s]", lockfile, strerror(errno));
+
+ goto fail;
+ }
+ value |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, value) < 0) {
+ log_error("Cannot set close-on-exec flag from pidfile [%s], "
+ "error was [%s]", lockfile, strerror(errno));
+
+ goto fail;
+ }
+
+ return 1;
+
+fail:
+ if (close(fd))
+ stack;
+ if (unlink(lockfile))
+ stack;
+
+ return 0;
+}