]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add parameter to wait for lock in file locking APIs
authorNehal J Wani <nehaljw.kkd1@gmail.com>
Mon, 17 Mar 2014 14:17:36 +0000 (19:47 +0530)
committerEric Blake <eblake@redhat.com>
Mon, 17 Mar 2014 16:04:47 +0000 (10:04 -0600)
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.

daemon/libvirtd.c
src/locking/lock_daemon.c
src/util/virfile.c
src/util/virfile.h
src/util/virlockspace.c
src/util/virpidfile.c
src/util/virpidfile.h

index a471b3b01f19a4247660a004afa35fbcbb5c4d0f..27c4fff6795f4d98a03ca366aabaf462b17b61d3 100644 (file)
@@ -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;
     }
index e047751d74bd26dfbb5d0ec301981e253379eb32..7dc4292a9255696eba55bc23dd1efe84e4ee122b 100644 (file)
@@ -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;
         }
index 6da564b43ecbb980a1d50513732e2e1562f53f80..a4a4827776af17036974b27841ced2123150fec0 100644 (file)
@@ -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;
 }
index 20baf6f9d2ec16d39f11816066bef4f7cc6ce417..302b74ffe78f8a85f9e5dfb882475b9e9cc3cab3 100644 (file)
@@ -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);
index 90a39bb5435c35959be684c02e89cb7a2753dd38..a187e1e3e6c1a6074b0067e7d485c9e96075d511 100644 (file)
@@ -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"),
index 298d57c94c534e7d7d6e3f4bd3759d6c045057af..28db24c9493093ea4a388f13090e52b0d807051b 100644 (file)
@@ -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);
index 3194a897be14814ec94e6d9caa12c15e67baae3c..2720206cccb0d8dc4df2f9e1d9e2d4dc7c110b61 100644 (file)
@@ -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,