diff options
author | drh <drh@noemail.net> | 2010-06-19 15:10:09 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2010-06-19 15:10:09 +0000 |
commit | 7234c6d6f6837325fd478f2cd33c1b7e2d01acad (patch) | |
tree | 42c0a89948bdf26e6797b05ee4553b11565f7d50 /src/os_unix.c | |
parent | be5c10477c17f0fe4916181b449e7575a96d5fec (diff) | |
download | sqlite-7234c6d6f6837325fd478f2cd33c1b7e2d01acad.tar.gz sqlite-7234c6d6f6837325fd478f2cd33c1b7e2d01acad.zip |
Change the unix VFS to always allocate shared-memory using a file in the
same directory as the database. Otherwise, a chroot might cause different
processes to use different shared memory files resulting in database
corruption.
FossilOrigin-Name: 2241788bc85fbc48e9cfecb95fe0a858338e37cb
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 64 |
1 files changed, 25 insertions, 39 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 574f48d18..8e3ca6684 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3274,19 +3274,21 @@ static void unixShmPurge(unixFile *pFd){ } } -/* Forward reference */ -static const char *unixTempFileDir(int); - /* -** Open a shared-memory area. This particular implementation uses -** mmapped files. -** -** zName is a filename used to identify the shared-memory area. The -** implementation does not (and perhaps should not) use this name -** directly, but rather use it as a template for finding an appropriate -** name for the shared-memory storage. In this implementation, the -** string "-index" is appended to zName and used as the name of the -** mmapped file. +** Open a shared-memory area associated with open database file fd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". We +** experimented with using files in /dev/tmp or an some other tmpfs mount. +** But if a file in a different directory from the database file is used, +** then differing access permissions or a chroot() might cause two different +** processes on the same database to end up using different files for +** shared memory - meaning that their memory would not really be shared - +** resulting in database corruption. ** ** When opening a new shared-memory file, if no other instances of that ** file are currently open, in this process or in other processes, then @@ -3300,8 +3302,8 @@ static int unixShmOpen( int rc; /* Result code */ struct unixFile *pDbFd; /* Underlying database file */ unixInodeInfo *pInode; /* The inode of fd */ - const char *zTempDir; /* Directory for temporary files */ - int nTempDir; /* Size of the zTempDir string */ + char *zShmFilename; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new sqlite3_shm object. */ @@ -3318,23 +3320,15 @@ static int unixShmOpen( pInode = pDbFd->pInode; pShmNode = pInode->pShmNode; if( pShmNode==0 ){ - zTempDir = unixTempFileDir(1); - if( zTempDir==0 ){ - unixLeaveMutex(); - sqlite3_free(p); - return SQLITE_CANTOPEN_NOTEMPDIR; - } - nTempDir = strlen(zTempDir); - pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nTempDir + 50 ); + nShmFilename = 5 + (int)strlen(pDbFd->zPath); + pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename ); if( pShmNode==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } memset(pShmNode, 0, sizeof(*pShmNode)); - pShmNode->zFilename = (char*)&pShmNode[1]; - sqlite3_snprintf(nTempDir+50, pShmNode->zFilename, - "%s/sqlite-wi-%x-%x", zTempDir, - (u32)pInode->fileId.dev, (u32)pInode->fileId.ino); + zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath); pShmNode->h = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; @@ -3344,7 +3338,7 @@ static int unixShmOpen( goto shm_open_err; } - pShmNode->h = open(pShmNode->zFilename, O_RDWR|O_CREAT, 0664); + pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, 0664); if( pShmNode->h<0 ){ rc = SQLITE_CANTOPEN_BKPT; goto shm_open_err; @@ -4157,7 +4151,7 @@ static int openDirectory(const char *zFilename, int *pFd){ ** Return the name of a directory in which to put temporary files. ** If no suitable temporary file directory can be found, return NULL. */ -static const char *unixTempFileDir(int allowShm){ +static const char *unixTempFileDir(void){ static const char *azDirs[] = { 0, 0, @@ -4172,19 +4166,11 @@ static const char *unixTempFileDir(int allowShm){ azDirs[0] = sqlite3_temp_directory; if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); - - if( allowShm ){ - zDir = "/dev/shm"; - i = 2; /* Skip the app-defined temp locations for shared-memory */ - }else{ - zDir = azDirs[0]; - i = 1; - } - for(; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ + for(i==0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ if( zDir==0 ) continue; if( stat(zDir, &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; - if( !allowShm && access(zDir, 07) ) continue; + if( access(zDir, 07) ) continue; break; } return zDir; @@ -4209,7 +4195,7 @@ static int unixGetTempname(int nBuf, char *zBuf){ */ SimulateIOError( return SQLITE_IOERR ); - zDir = unixTempFileDir(0); + zDir = unixTempFileDir(); if( zDir==0 ) zDir = "."; /* Check that the output buffer is large enough for the temporary file |