AFS (the Andrew FileSystem) supports whole-file locks but not
byte-range locks. Unfortunately, it has a problematic "feature"
whereby it will claim to grant requests for byte-range locks, but not
actually perform any locking activity. This unfortunately can easily
lead to corruption for applications like sqlite.
The patch below tells sqlite to always use whole-file locks for files
residing in a filesystem of type "afs". I have confirmed that with
this patch (and SQLITE_ENABLE_LOCKING_STYLE), one can successfully
write concurrently to a single database file from two different AFS
clients without corruption. Very cool!
The development release of OpenAFS (1.5) has "proper" support for
byte-range locks; when it is finalized I will contribute code to
detect versions which properly support byte-range locking.
This patch also adds --enable-locking-style to the configure options
and is capable of detecting many popular filesystem types on both
Darwin (nice API that returns strings) or Linux (which has no API for
getting the descriptive string, unfortunately).
Please let me know if any of this should be done differently.
- a
Index: configure.ac
===================================================================
RCS file: /sqlite/sqlite/configure.ac,v
retrieving revision 1.26
diff -B -u -b -r1.26 configure.ac
--- configure.ac 3 Jun 2006 18:02:18 -0000 1.26
+++ configure.ac 25 Dec 2006 00:41:58 -0000
@@ -318,6 +318,21 @@
AC_SUBST(XTHREADCONNECT)
##########
+# Do we want to allow different locking styles?
+#
+AC_ARG_ENABLE(locking-style,
+AC_HELP_STRING([--enable-locking-style],[Enable different locking
styles]),,enable_lockingstyle=no)
+AC_MSG_CHECKING([whether to allow connections to be shared across threads])
+if test "$enable_lockingstyle" = "no"; then
+ ENABLELOCKINGSTYLE=''
+ AC_MSG_RESULT([no])
+else
+ ENABLELOCKINGSTYLE='-DSQLITE_ENABLE_LOCKING_STYLE=1'
+ AC_MSG_RESULT([yes])
+fi
+AC_SUBST(ENABLELOCKINGSTYLE)
+
+##########
# Do we want to set threadsOverrideEachOthersLocks variable to be 1 (true) by
# default. Normally, a test at runtime is performed to determine the
# appropriate value of this variable. Use this option only if you're sure that
@@ -673,7 +688,35 @@
# Redefine fdatasync as fsync on systems that lack fdatasync
#--------------------------------------------------------------------
+AC_CHECK_HEADER([sys/statfs.h], [TARGET_CFLAGS="$TARGET_CFLAGS
-DHAVE_SYS_STATFS_H=1"],)
+
AC_CHECK_FUNC(fdatasync, [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_FDATASYNC=1"])
+AC_CHECK_FUNC(fsctl, [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_FSCTL=1"])
+
+AC_CHECK_MEMBER(struct statfs.f_flags,
+ [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_STATFS_F_FLAGS=1"],,
+ [
+ #include <sys/ioctl.h>
+ #include <sys/param.h>
+ #include <sys/mount.h>
+ ])
+
+AC_CHECK_MEMBER(struct statfs.f_type,
+ [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_STATFS_F_TYPE=1"],,
+ [
+ #include <sys/ioctl.h>
+ #include <sys/statfs.h>
+ #include <sys/param.h>
+ #include <sys/mount.h>
+ ])
+
+AC_CHECK_MEMBER(struct statfs.f_fstypename,
+ [TARGET_CFLAGS="$TARGET_CFLAGS -DHAVE_STATFS_F_FSTYPENAME=1"],,
+ [
+ #include <sys/ioctl.h>
+ #include <sys/param.h>
+ #include <sys/mount.h>
+ ])
#########
# Put out accumulated miscellaneous LIBRARIES
Index: Makefile.in
===================================================================
RCS file: /sqlite/sqlite/Makefile.in,v
retrieving revision 1.160
diff -B -u -b -r1.160 Makefile.in
--- Makefile.in 21 Dec 2006 22:38:23 -0000 1.160
+++ Makefile.in 25 Dec 2006 00:41:58 -0000
@@ -32,7 +32,7 @@
# Omitting the define will cause extra debugging code to be inserted and
# includes extra comments when "EXPLAIN stmt" is used.
#
-TCC += @TARGET_DEBUG@ @XTHREADCONNECT@
+TCC += @TARGET_DEBUG@ @XTHREADCONNECT@ @ENABLELOCKINGSTYLE@
# Compiler options needed for programs that use the TCL library.
#
Index: src/os_unix.c
===================================================================
RCS file: /sqlite/sqlite/src/os_unix.c,v
retrieving revision 1.114
diff -B -u -b -r1.114 os_unix.c
--- src/os_unix.c 21 Dec 2006 01:29:23 -0000 1.114
+++ src/os_unix.c 25 Dec 2006 00:41:59 -0000
@@ -52,6 +52,9 @@
#ifdef SQLITE_ENABLE_LOCKING_STYLE
#include <sys/ioctl.h>
#include <sys/param.h>
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif /* HAVE_SYS_STATFS_H */
#include <sys/mount.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -587,15 +590,18 @@
#ifdef SQLITE_FIXED_LOCKING_STYLE
return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE;
-#else
+#else /* SQLITE_FIXED_LOCKING_STYLE */
struct statfs fsInfo;
if (statfs(filePath, &fsInfo) == -1)
return sqlite3TestLockingStyle(filePath, fd);
+#ifdef HAVE_STATFS_F_FLAGS
if (fsInfo.f_flags & MNT_RDONLY)
return noLockingStyle;
+#endif /* HAVE_STATFS_F_FLAGS */
+#ifdef HAVE_STATFS_F_FSTYPENAME
if( (!strcmp(fsInfo.f_fstypename, "hfs")) ||
(!strcmp(fsInfo.f_fstypename, "ufs")) )
return posixLockingStyle;
@@ -609,14 +615,40 @@
if(!strcmp(fsInfo.f_fstypename, "smbfs"))
return flockLockingStyle;
+ if(!strcmp(fsInfo.f_fstypename, "afs"))
+ return flockLockingStyle;
+
if(!strcmp(fsInfo.f_fstypename, "msdos"))
return dotlockLockingStyle;
if(!strcmp(fsInfo.f_fstypename, "webdav"))
return unsupportedLockingStyle;
+#else /* HAVE_STATFS_F_FSTYPENAME */
+# ifdef HAVE_STATFS_F_TYPE
+ switch(fsInfo.f_type) {
+ case 0x4d44: // DOS/FAT
+ return dotlockLockingStyle;
+
+ case 0x6969: // NFS
+ case 0x564c: // Netware NCPFS
+ return sqlite3TestLockingStyle(filePath, fd);
+
+ case 0x517B: // SMBFS
+ case 0x0000: // AFS or unknown
+ return flockLockingStyle;
+
+ case 0x00011954: // UFS
+ case 0x58465342: // XFS
+ case 0x137D: // ext1fs
+ case 0xEF51: // ext2fs
+ case 0xEF53: // ext2fs
+ return posixLockingStyle;
+ }
+# endif /* HAVE_STATFS_F_TYPE */
+#endif /* HAVE_STATFS_F_FSTYPENAME */
+#endif /* SQLITE_FIXED_LOCKING_STYLE */
return sqlite3TestLockingStyle(filePath, fd);
-#endif // SQLITE_FIXED_LOCKING_STYLE
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -1674,6 +1706,8 @@
#ifdef SQLITE_ENABLE_LOCKING_STYLE
+
+#ifdef HAVE_FSCTL
#pragma mark AFP Support
/*
@@ -1987,7 +2021,7 @@
*pId = 0;
return SQLITE_OK;
}
-
+#endif /* HAVE_FSCTL */
#pragma mark flock() style locking
@@ -2341,6 +2375,8 @@
};
#ifdef SQLITE_ENABLE_LOCKING_STYLE
+
+#ifdef HAVE_FSCTL
/*
** This vector defines all the methods that can operate on an OsFile
** for unix with AFP style file locking.
@@ -2361,6 +2397,7 @@
unixLockState,
afpUnixCheckReservedLock,
};
+#endif /* HAVE_FSCTL */
/*
** This vector defines all the methods that can operate on an OsFile
@@ -2486,6 +2523,7 @@
}else{
*pNew = f;
switch(lockingStyle) {
+#ifdef HAVE_FSCTL
case afpLockingStyle:
/* afp locking uses the file path so it needs to be included in
** the afpLockingContext */
@@ -2498,6 +2536,7 @@
zFilename);
srandomdev();
break;
+#endif /* HAVE_FSCTL */
case flockLockingStyle:
/* flock locking doesn't need additional lockingContext information */
pNew->pMethod = &sqlite3FlockLockingUnixIoMethod;
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------