mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-05 22:05:47 +00:00
Add parameter to wait for lock in file locking APIs
Our current pidfile acquire APis (virPidFileAcquire) simply return -1 upon failure to acquire a lock. This patch adds a parameter 'bool waitForLock' which instructs the APIs if we want to make it block and wait for the lock or not.
This commit is contained in:
parent
cb873e9d15
commit
2250a2b5d2
@ -1369,7 +1369,7 @@ int main(int argc, char **argv) {
|
|||||||
umask(old_umask);
|
umask(old_umask);
|
||||||
|
|
||||||
/* Try to claim the pidfile, exiting if we can't */
|
/* 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;
|
ret = VIR_DAEMON_ERR_PIDFILE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1020,7 @@ virLockDaemonPostExecRestart(const char *state_file,
|
|||||||
|
|
||||||
/* Re-claim PID file now as we will not be daemonizing */
|
/* Re-claim PID file now as we will not be daemonizing */
|
||||||
if (pid_file &&
|
if (pid_file &&
|
||||||
(*pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0)
|
(*pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(lockDaemon = virLockDaemonNewPostExecRestart(object, privileged)))
|
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 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;
|
ret = VIR_LOCK_DAEMON_ERR_PIDFILE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -339,13 +339,14 @@ virFileWrapperFdFree(virFileWrapperFdPtr wfd)
|
|||||||
* @shared: type of lock to acquire
|
* @shared: type of lock to acquire
|
||||||
* @start: byte offset to start lock
|
* @start: byte offset to start lock
|
||||||
* @len: length of lock (0 to acquire entire remaining file from @start)
|
* @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
|
* Attempt to acquire a lock on the file @fd. If @shared
|
||||||
* is true, then a shared lock will be acquired,
|
* is true, then a shared lock will be acquired,
|
||||||
* otherwise an exclusive lock will be acquired. If
|
* otherwise an exclusive lock will be acquired. If
|
||||||
* the lock cannot be acquired, an error will be
|
* the lock cannot be acquired, an error will be
|
||||||
* returned. This will not wait to acquire the lock if
|
* returned. If @waitForLock is true, this will wait
|
||||||
* another process already holds it.
|
* for the lock if another process has already acquired it.
|
||||||
*
|
*
|
||||||
* The lock will be released when @fd is closed. The lock
|
* The lock will be released when @fd is closed. The lock
|
||||||
* will also be released if *any* other open file descriptor
|
* will also be released if *any* other open file descriptor
|
||||||
@ -356,7 +357,7 @@ virFileWrapperFdFree(virFileWrapperFdPtr wfd)
|
|||||||
*
|
*
|
||||||
* Returns 0 on success, or -errno otherwise
|
* 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 = {
|
struct flock fl = {
|
||||||
.l_type = shared ? F_RDLCK : F_WRLCK,
|
.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,
|
.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 -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -402,7 +405,8 @@ int virFileUnlock(int fd, off_t start, off_t len)
|
|||||||
int virFileLock(int fd ATTRIBUTE_UNUSED,
|
int virFileLock(int fd ATTRIBUTE_UNUSED,
|
||||||
bool shared ATTRIBUTE_UNUSED,
|
bool shared ATTRIBUTE_UNUSED,
|
||||||
off_t start ATTRIBUTE_UNUSED,
|
off_t start ATTRIBUTE_UNUSED,
|
||||||
off_t len ATTRIBUTE_UNUSED)
|
off_t len ATTRIBUTE_UNUSED,
|
||||||
|
bool waitForLock ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ int virFileWrapperFdClose(virFileWrapperFdPtr dfd);
|
|||||||
|
|
||||||
void virFileWrapperFdFree(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);
|
int virFileUnlock(int fd, off_t start, off_t len);
|
||||||
|
|
||||||
typedef int (*virFileRewriteFunc)(int fd, void *opaque);
|
typedef int (*virFileRewriteFunc)(int fd, void *opaque);
|
||||||
|
@ -82,7 +82,7 @@ static void virLockSpaceResourceFree(virLockSpaceResourcePtr res)
|
|||||||
if (res->flags & VIR_LOCK_SPACE_ACQUIRE_SHARED) {
|
if (res->flags & VIR_LOCK_SPACE_ACQUIRE_SHARED) {
|
||||||
/* We must upgrade to an exclusive lock to ensure
|
/* We must upgrade to an exclusive lock to ensure
|
||||||
* no one else still has it before trying to delete */
|
* 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");
|
VIR_DEBUG("Could not upgrade shared lease to exclusive, not deleting");
|
||||||
} else {
|
} else {
|
||||||
if (unlink(res->path) < 0 &&
|
if (unlink(res->path) < 0 &&
|
||||||
@ -155,7 +155,7 @@ virLockSpaceResourceNew(virLockSpacePtr lockspace,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virFileLock(res->fd, shared, 0, 1) < 0) {
|
if (virFileLock(res->fd, shared, 0, 1, false) < 0) {
|
||||||
if (errno == EACCES || errno == EAGAIN) {
|
if (errno == EACCES || errno == EAGAIN) {
|
||||||
virReportError(VIR_ERR_RESOURCE_BUSY,
|
virReportError(VIR_ERR_RESOURCE_BUSY,
|
||||||
_("Lockspace resource '%s' is locked"),
|
_("Lockspace resource '%s' is locked"),
|
||||||
@ -202,7 +202,7 @@ virLockSpaceResourceNew(virLockSpacePtr lockspace,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virFileLock(res->fd, shared, 0, 1) < 0) {
|
if (virFileLock(res->fd, shared, 0, 1, false) < 0) {
|
||||||
if (errno == EACCES || errno == EAGAIN) {
|
if (errno == EACCES || errno == EAGAIN) {
|
||||||
virReportError(VIR_ERR_RESOURCE_BUSY,
|
virReportError(VIR_ERR_RESOURCE_BUSY,
|
||||||
_("Lockspace resource '%s' is locked"),
|
_("Lockspace resource '%s' is locked"),
|
||||||
|
@ -372,6 +372,7 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int virPidFileAcquirePath(const char *path,
|
int virPidFileAcquirePath(const char *path,
|
||||||
|
bool waitForLock,
|
||||||
pid_t pid)
|
pid_t pid)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
@ -405,7 +406,7 @@ int virPidFileAcquirePath(const char *path,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virFileLock(fd, false, 0, 1) < 0) {
|
if (virFileLock(fd, false, 0, 1, waitForLock) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("Failed to acquire pid file '%s'"),
|
_("Failed to acquire pid file '%s'"),
|
||||||
path);
|
path);
|
||||||
@ -448,6 +449,7 @@ int virPidFileAcquirePath(const char *path,
|
|||||||
|
|
||||||
int virPidFileAcquire(const char *dir,
|
int virPidFileAcquire(const char *dir,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
bool waitForLock,
|
||||||
pid_t pid)
|
pid_t pid)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -463,7 +465,7 @@ int virPidFileAcquire(const char *dir,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = virPidFileAcquirePath(pidfile, pid);
|
rc = virPidFileAcquirePath(pidfile, waitForLock, pid);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(pidfile);
|
VIR_FREE(pidfile);
|
||||||
|
@ -56,9 +56,11 @@ int virPidFileDelete(const char *dir,
|
|||||||
|
|
||||||
|
|
||||||
int virPidFileAcquirePath(const char *path,
|
int virPidFileAcquirePath(const char *path,
|
||||||
|
bool waitForLock,
|
||||||
pid_t pid) ATTRIBUTE_RETURN_CHECK;
|
pid_t pid) ATTRIBUTE_RETURN_CHECK;
|
||||||
int virPidFileAcquire(const char *dir,
|
int virPidFileAcquire(const char *dir,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
bool waitForLock,
|
||||||
pid_t pid) ATTRIBUTE_RETURN_CHECK;
|
pid_t pid) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
int virPidFileReleasePath(const char *path,
|
int virPidFileReleasePath(const char *path,
|
||||||
|
Loading…
Reference in New Issue
Block a user