diff options
author | Fabio M. Di Nitto <fdinitto@redhat.com> | 2010-07-13 13:51:01 +0000 |
---|---|---|
committer | Fabio M. Di Nitto <fdinitto@redhat.com> | 2010-07-13 13:51:01 +0000 |
commit | 8c4e8a185a371ee6133168603890bfa923163f88 (patch) | |
tree | 0200fb53a4edf74f7ec6a9ee6dd2c12b29df8aa7 /libdm/libdm-file.c | |
parent | 8e3da446f4d81f693ead821db6cf1ca837ab19fc (diff) | |
download | lvm2-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.c | 82 |
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; +} |