[libvirt] [PATCH 1/5] Add virFileLock and virFileUnlock APIs

Daniel P. Berrange berrange at redhat.com
Wed Aug 10 15:37:24 UTC 2011


From: "Daniel P. Berrange" <berrange at redhat.com>

Add some simple wrappers around the fcntl() discretionary file
locking capability.

* src/util/util.c, src/util/util.h, src/libvirt_private.syms: Add
  virFileLock and virFileUnlock APIs
---
 src/libvirt_private.syms |    2 +
 src/util/virfile.c       |   83 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |    3 ++
 3 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 830222b..261f3e0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1039,6 +1039,7 @@ virFileFindMountPoint;
 virFileHasSuffix;
 virFileIsExecutable;
 virFileLinkPointsTo;
+virFileLock;
 virFileMakePath;
 virFileMatchesNameSuffix;
 virFileOpenAs;
@@ -1051,6 +1052,7 @@ virFileReadPidPath;
 virFileResolveLink;
 virFileSanitizePath;
 virFileStripSuffix;
+virFileUnlock;
 virFileWaitForDevices;
 virFileWriteStr;
 virFindFileInPath;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 8b32518..1346c1a 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -251,3 +251,86 @@ virFileDirectFdFree(virFileDirectFdPtr dfd)
     virCommandFree(dfd->cmd);
     VIR_FREE(dfd);
 }
+
+
+#ifndef WIN32
+/**
+ * virFileLock:
+ * @fd: file descriptor to acquire the lock on
+ * @shared: type of lock to acquire
+ * @start: byte offset to start lock
+ * @len: length of lock (0 to acquire entire remaining file from @start)
+ *
+ * Attempt to acquire a lock on the file @fd. If @shared
+ * is true, then the 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.
+ *
+ * The lock will be released will @fd is closed. The lock
+ * will also be released if *any* other open file descriptor
+ * pointing to the same underlying file is closed. As such
+ * this function should not be relied on in multi-threaded
+ * apps where other threads can be opening/closing arbitrary
+ * files.
+ *
+ * Returns: 0 on success, or -errno otherwise
+ */
+int virFileLock(int fd, bool shared, off_t start, off_t len)
+{
+    struct flock fl = {
+        .l_type = shared ? F_RDLCK : F_WRLCK,
+        .l_whence = SEEK_SET,
+        .l_start = start,
+        .l_len = len,
+    };
+
+    if (fcntl(fd, F_SETLK, &fl) < 0)
+        return -errno;
+
+    return 0;
+}
+
+
+/**
+ * virFileUnlock:
+ * @fd: file descriptor to release the lock on
+ * @start: byte offset to start unlock
+ * @len: length of lock (0 to release entire remaining file from @start)
+ *
+ * Release a lock previously acquired with virFileUnlock().
+ * NB the lock will also be released if any open file descriptor
+ * pointing to the same file as @fd is closed
+ *
+ * Returns 0 on succcess, or -errno on error
+ */
+int virFileUnlock(int fd, off_t start, off_t len)
+{
+    struct flock fl = {
+        .l_type = F_UNLCK,
+        .l_whence = SEEK_SET,
+        .l_start = start,
+        .l_len = len,
+    };
+
+    if (fcntl(fd, F_SETLK, &fl) < 0)
+        return -errno;
+
+    return 0;
+}
+#else
+int virFileLock(int fd ATTRIBUTE_UNUSED,
+                bool shared ATTRIBUTE_UNUSED,
+                off_t start ATTRIBUTE_UNUSED,
+                off_t len ATTRIBUTE_UNUSED)
+{
+    return -ENOSYS;
+}
+int virFileUnlock(int fd ATTRIBUTE_UNUSED,
+                  off_t start ATTRIBUTE_UNUSED,
+                  off_t len ATTRIBUTE_UNUSED)
+{
+    return -ENOSYS;
+}
+#endif
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 0906568..e025614 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -65,4 +65,7 @@ int virFileDirectFdClose(virFileDirectFdPtr dfd);
 
 void virFileDirectFdFree(virFileDirectFdPtr dfd);
 
+int virFileLock(int fd, bool shared, off_t start, off_t len);
+int virFileUnlock(int fd, off_t start, off_t len);
+
 #endif /* __VIR_FILES_H */
-- 
1.7.6




More information about the libvir-list mailing list