diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index a471b3b01f19a4247660a004afa35fbcbb5c4d0f..27c4fff6795f4d98a03ca366aabaf462b17b61d3 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1369,7 +1369,7 @@ int main(int argc, char **argv) { umask(old_umask); /* Try to claim the pidfile, exiting if we can't */ - if ((pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) { + if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) { ret = VIR_DAEMON_ERR_PIDFILE; goto cleanup; } diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index e047751d74bd26dfbb5d0ec301981e253379eb32..7dc4292a9255696eba55bc23dd1efe84e4ee122b 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -1020,7 +1020,7 @@ virLockDaemonPostExecRestart(const char *state_file, /* Re-claim PID file now as we will not be daemonizing */ if (pid_file && - (*pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) + (*pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) goto cleanup; if (!(lockDaemon = virLockDaemonNewPostExecRestart(object, privileged))) @@ -1382,7 +1382,7 @@ int main(int argc, char **argv) { } /* If we have a pidfile set, claim it now, exiting if already taken */ - if ((pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) { + if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) { ret = VIR_LOCK_DAEMON_ERR_PIDFILE; goto cleanup; } diff --git a/src/util/virfile.c b/src/util/virfile.c index 6da564b43ecbb980a1d50513732e2e1562f53f80..a4a4827776af17036974b27841ced2123150fec0 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -339,13 +339,14 @@ virFileWrapperFdFree(virFileWrapperFdPtr wfd) * @shared: type of lock to acquire * @start: byte offset to start lock * @len: length of lock (0 to acquire entire remaining file from @start) + * @waitForLock: wait for previously held lock or not * * Attempt to acquire a lock on the file @fd. If @shared * is true, then a shared lock will be acquired, * otherwise an exclusive lock will be acquired. If * the lock cannot be acquired, an error will be - * returned. This will not wait to acquire the lock if - * another process already holds it. + * returned. If @waitForLock is true, this will wait + * for the lock if another process has already acquired it. * * The lock will be released when @fd is closed. The lock * will also be released if *any* other open file descriptor @@ -356,7 +357,7 @@ virFileWrapperFdFree(virFileWrapperFdPtr wfd) * * Returns 0 on success, or -errno otherwise */ -int virFileLock(int fd, bool shared, off_t start, off_t len) +int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForLock) { struct flock fl = { .l_type = shared ? F_RDLCK : F_WRLCK, @@ -365,7 +366,9 @@ int virFileLock(int fd, bool shared, off_t start, off_t len) .l_len = len, }; - if (fcntl(fd, F_SETLK, &fl) < 0) + int cmd = waitForLock ? F_SETLKW : F_SETLK; + + if (fcntl(fd, cmd, &fl) < 0) return -errno; return 0; @@ -402,7 +405,8 @@ int virFileUnlock(int fd, off_t start, off_t len) int virFileLock(int fd ATTRIBUTE_UNUSED, bool shared ATTRIBUTE_UNUSED, off_t start ATTRIBUTE_UNUSED, - off_t len ATTRIBUTE_UNUSED) + off_t len ATTRIBUTE_UNUSED, + bool waitForLock ATTRIBUTE_UNUSED) { return -ENOSYS; } diff --git a/src/util/virfile.h b/src/util/virfile.h index 20baf6f9d2ec16d39f11816066bef4f7cc6ce417..302b74ffe78f8a85f9e5dfb882475b9e9cc3cab3 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -97,7 +97,7 @@ int virFileWrapperFdClose(virFileWrapperFdPtr dfd); void virFileWrapperFdFree(virFileWrapperFdPtr dfd); -int virFileLock(int fd, bool shared, off_t start, off_t len); +int virFileLock(int fd, bool shared, off_t start, off_t len, bool waitForLock); int virFileUnlock(int fd, off_t start, off_t len); typedef int (*virFileRewriteFunc)(int fd, void *opaque); diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c index 90a39bb5435c35959be684c02e89cb7a2753dd38..a187e1e3e6c1a6074b0067e7d485c9e96075d511 100644 --- a/src/util/virlockspace.c +++ b/src/util/virlockspace.c @@ -82,7 +82,7 @@ static void virLockSpaceResourceFree(virLockSpaceResourcePtr res) if (res->flags & VIR_LOCK_SPACE_ACQUIRE_SHARED) { /* We must upgrade to an exclusive lock to ensure * no one else still has it before trying to delete */ - if (virFileLock(res->fd, false, 0, 1) < 0) { + if (virFileLock(res->fd, false, 0, 1, false) < 0) { VIR_DEBUG("Could not upgrade shared lease to exclusive, not deleting"); } else { if (unlink(res->path) < 0 && @@ -155,7 +155,7 @@ virLockSpaceResourceNew(virLockSpacePtr lockspace, goto error; } - if (virFileLock(res->fd, shared, 0, 1) < 0) { + if (virFileLock(res->fd, shared, 0, 1, false) < 0) { if (errno == EACCES || errno == EAGAIN) { virReportError(VIR_ERR_RESOURCE_BUSY, _("Lockspace resource '%s' is locked"), @@ -202,7 +202,7 @@ virLockSpaceResourceNew(virLockSpacePtr lockspace, goto error; } - if (virFileLock(res->fd, shared, 0, 1) < 0) { + if (virFileLock(res->fd, shared, 0, 1, false) < 0) { if (errno == EACCES || errno == EAGAIN) { virReportError(VIR_ERR_RESOURCE_BUSY, _("Lockspace resource '%s' is locked"), diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 298d57c94c534e7d7d6e3f4bd3759d6c045057af..28db24c9493093ea4a388f13090e52b0d807051b 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -372,6 +372,7 @@ cleanup: } int virPidFileAcquirePath(const char *path, + bool waitForLock, pid_t pid) { int fd = -1; @@ -405,7 +406,7 @@ int virPidFileAcquirePath(const char *path, return -1; } - if (virFileLock(fd, false, 0, 1) < 0) { + if (virFileLock(fd, false, 0, 1, waitForLock) < 0) { virReportSystemError(errno, _("Failed to acquire pid file '%s'"), path); @@ -448,6 +449,7 @@ int virPidFileAcquirePath(const char *path, int virPidFileAcquire(const char *dir, const char *name, + bool waitForLock, pid_t pid) { int rc = 0; @@ -463,7 +465,7 @@ int virPidFileAcquire(const char *dir, goto cleanup; } - rc = virPidFileAcquirePath(pidfile, pid); + rc = virPidFileAcquirePath(pidfile, waitForLock, pid); cleanup: VIR_FREE(pidfile); diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h index 3194a897be14814ec94e6d9caa12c15e67baae3c..2720206cccb0d8dc4df2f9e1d9e2d4dc7c110b61 100644 --- a/src/util/virpidfile.h +++ b/src/util/virpidfile.h @@ -56,9 +56,11 @@ int virPidFileDelete(const char *dir, int virPidFileAcquirePath(const char *path, + bool waitForLock, pid_t pid) ATTRIBUTE_RETURN_CHECK; int virPidFileAcquire(const char *dir, const char *name, + bool waitForLock, pid_t pid) ATTRIBUTE_RETURN_CHECK; int virPidFileReleasePath(const char *path,