For the record,

  "The author or authors of this code dedicate any and all copyright
  interest in this code to the public domain. We make this dedication
  for the benefit of the public at large and to the detriment of our
  heirs and successors. We intend this dedication to be an overt act
  of relinquishment in perpetuity of all present and future rights
  this code under copyright law."

I have mailed off the copyright release.

  - a

Adam Megacz <[EMAIL PROTECTED]> writes:
> In addition to the functionality in the previous patch, this patch
> includes a new function testProcessLockingBehavior(), which is
> conceptually similar to testThreadLockingBehavior but using fork()
> instead of pthread_create().
>
> This might sound obvious: lock the first byte of a file, fork() a
> child, and have the child attempt to lock that same byte -- this
> should always fail.  Unfortunately all currently-deployed non-Linux
> AFS clients will actually "grant" locks to both processes.
>
> The added code checks for this behavior empirically before proceeding
> with posixLockingStyle.  If nonsensical behavior is observed, it
> automatically falls back to whole-file locks.
>
>   - 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      26 Dec 2006 01:25:40 -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       26 Dec 2006 01:25:40 -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     26 Dec 2006 01:25:41 -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 */
>  
> @@ -479,6 +482,52 @@
>  #define fcntl lockTrace
>  #endif /* SQLITE_LOCK_TRACE */
>  
> +#ifdef SQLITE_ENABLE_LOCKING_STYLE
> +/**
> + *  Check to see if the OS fcntl() byte-range locking call will "lie"
> + *  to us and grant a lock that is not enforced.  This happens notably
> + *  with files in AFS (OpenAFS client <1.5.0, all OSes but Linux).
> + *
> + *  Returns zero if byte-range locks appear to work as expected.
> + */
> +static int testProcessLockingBehavior(int fd_orig){
> +  int fd;
> +  int result;
> +  struct flock lock;
> +  
> +  fd = dup(fd_orig);
> +  if( fd<0 ) return 1;
> +  memset(&lock, 0, sizeof(struct flock));
> +  lock.l_type = F_WRLCK;
> +  lock.l_len = 1;
> +  lock.l_start = 0;
> +  lock.l_whence = SEEK_SET;
> +  
> +  result = fcntl(fd, F_SETLK, &lock);
> +  if (result) {
> +    TRACE1("testProcessLockingBehavior(): initial lock in parent failed\n");
> +    close(fd);
> +    return 1;
> +  }
> +  
> +  if (fork()==0) {
> +    result = fcntl(fd, F_SETLK, &lock);
> +    exit(result);
> +    
> +  } else {
> +    wait(&result);
> +    if (!result) {
> +      TRACE1("testProcessLockingBehavior(): parent and child both got 
> locks\n");
> +      close(fd);
> +      return 1;
> +    }
> +  }
> +  
> +  close(fd);
> +  return 0;
> +}
> +#endif /* SQLITE_ENABLE_LOCKING_STYLE */
> +
>  /*
>  ** The testThreadLockingBehavior() routine launches two separate
>  ** threads on this routine.  This routine attempts to lock a file
> @@ -587,15 +636,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 +661,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 +1752,8 @@
>  
>  
>  #ifdef SQLITE_ENABLE_LOCKING_STYLE
> +
> +#ifdef HAVE_FSCTL
>  #pragma mark AFP Support
>  
>  /*
> @@ -1987,7 +2067,7 @@
>    *pId = 0;
>    return SQLITE_OK;
>  }
> -
> +#endif /* HAVE_FSCTL */
>  
>  #pragma mark flock() style locking
>  
> @@ -2341,6 +2421,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 +2443,7 @@
>      unixLockState,
>      afpUnixCheckReservedLock,
>  };
> +#endif /* HAVE_FSCTL */
>  
>  /*
>   ** This vector defines all the methods that can operate on an OsFile
> @@ -2451,6 +2534,13 @@
>    int rc;
>  
>    lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
> +
> +  if ( lockingStyle == posixLockingStyle ) {
> +    // downgrade to flock() if byte-range locks appear to work strangely
> +    if (!testProcessLockingBehavior())
> +      lockingStyle = flockLockingStyle;
> +  }
> +
>    if ( lockingStyle == posixLockingStyle ) {
>      sqlite3OsEnterMutex();
>      rc = findLockInfo(h, &f.pLock, &f.pOpen);
> @@ -2459,7 +2549,6 @@
>        close(h);
>        unlink(zFilename);
>        return SQLITE_NOMEM;
> -    }
>    } else {
>      //  pLock and pOpen are only used for posix advisory locking 
>      f.pLock = NULL;
> @@ -2486,6 +2575,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 +2588,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]
> -----------------------------------------------------------------------------
>
>

-- 
PGP/GPG: 5C9F F366 C9CF 2145 E770  B1B8 EFB1 462D A146 C380

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to