From: drh Date: Sat, 19 Jun 2010 15:10:09 +0000 (+0000) Subject: Change the unix VFS to always allocate shared-memory using a file in the X-Git-Tag: version-3.7.2~258 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=7234c6d6f6837325fd478f2cd33c1b7e2d01acad;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index eeefca1a8d..483d16970a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Apply\s[b9b11855e8]\s(the\salternate\sfix\sto\s[fc62af4523])\sto\sthe\strunk. -D 2010-06-17T17:05:54 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Change\sthe\sunix\sVFS\sto\salways\sallocate\sshared-memory\susing\sa\sfile\sin\sthe\nsame\sdirectory\sas\sthe\sdatabase.\s\sOtherwise,\sa\schroot\smight\scause\sdifferent\nprocesses\sto\suse\sdifferent\sshared\smemory\sfiles\sresulting\sin\sdatabase\ncorruption. +D 2010-06-19T15:10:10 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -154,7 +157,7 @@ F src/os.c 9c4a2f82a50306a33907678ec0187b6ad1486bfe F src/os.h d7775504a51e6e0d40315aa427b3e229ff9ff9ca F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19 -F src/os_unix.c ae173c9f6afaa58b2833a1c95c6cd32021755c42 +F src/os_unix.c a76d1952ac7984574701c48b665220b871c5c9a5 F src/os_win.c dfde7d33c446e89dd9a277c036f2c4cc564b3138 F src/pager.c 4fe451d68950002eb985e6325d666ab54956a37f F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd @@ -823,7 +826,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 7c3a86b9c7e2a35ce755c32b38e911e79d843fad -R 1e4481b965cd36ec30ba83a04296f9cc -U dan -Z b00e14e0e21b5f60f6931c141403c159 +P 9a949a3a5c32b8bfbb94e10e18d050ec80a25553 +R acdbeeb43afddd9408962cb351e87aec +U drh +Z 2d4cd5d2db2524a9b5137cfeafb22e1e +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMHN3WoxKgR168RlERApgaAJ48Uha0kqQFVEwHVS03zg+AKsjJKwCfSU8L +jmliKcE06t2NitzknAIS5tM= +=X+y+ +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 97d2603404..42d1b1066c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a949a3a5c32b8bfbb94e10e18d050ec80a25553 \ No newline at end of file +2241788bc85fbc48e9cfecb95fe0a858338e37cb \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 574f48d189..8e3ca66847 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