On Wed, Aug 10, 2011 at 16:37:24 +0100, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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, s/the // ^^^^^ > + * 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 s/will/when/ I guess ^^^^ > + * 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 The documentation builder doesn't want ':' after "Returns" IIRC. Ah, but this is not a public API and documentation won't be generated from this block anyway so it doesn't really matter. > + */ > +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 */ ACK with nits fixed. Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list