Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2241788bc85fbc48e9cfecb95fe0a858 |
User & Date: | drh 2010-06-19 15:10:10.000 |
Context
2010-06-19
| ||
23:53 | Fix an uninitialized variable in os_unix.c. (check-in: 822a0283c6 user: drh tags: trunk) | |
15:10 | 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. (check-in: 2241788bc8 user: drh tags: trunk) | |
2010-06-17
| ||
17:05 | Apply [b9b11855e8] (the alternate fix to [fc62af4523]) to the trunk. (check-in: 9a949a3a5c user: dan tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
3270 3271 3272 3273 3274 3275 3276 | sqlite3_free(p->apRegion); if( p->h>=0 ) close(p->h); p->pInode->pShmNode = 0; sqlite3_free(p); } } | < < < | | | > > > | | | | > > | | | < < < < < < | | | | < < | | 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 | sqlite3_free(p->apRegion); if( p->h>=0 ) close(p->h); p->pInode->pShmNode = 0; sqlite3_free(p); } } /* ** 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 ** the file must be truncated to zero length or have its header cleared. */ static int unixShmOpen( sqlite3_file *fd /* The file descriptor of the associated database */ ){ struct unixShm *p = 0; /* The connection to be opened */ struct unixShmNode *pShmNode = 0; /* The underlying mmapped file */ int rc; /* Result code */ struct unixFile *pDbFd; /* Underlying database file */ unixInodeInfo *pInode; /* The inode of fd */ 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. */ p = sqlite3_malloc( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); pDbFd = (struct unixFile*)fd; assert( pDbFd->pShm==0 ); /* Check to see if a unixShmNode object already exists. Reuse an existing ** one if present. Create a new one if necessary. */ unixEnterMutex(); pInode = pDbFd->pInode; pShmNode = pInode->pShmNode; if( pShmNode==0 ){ 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)); 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; pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, 0664); if( pShmNode->h<0 ){ rc = SQLITE_CANTOPEN_BKPT; goto shm_open_err; } /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. |
︙ | ︙ | |||
4153 4154 4155 4156 4157 4158 4159 | return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT); } /* ** Return the name of a directory in which to put temporary files. ** If no suitable temporary file directory can be found, return NULL. */ | | < < < < < < < < | | | 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 | return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT); } /* ** 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(void){ static const char *azDirs[] = { 0, 0, "/var/tmp", "/usr/tmp", "/tmp", 0 /* List terminator */ }; unsigned int i; struct stat buf; const char *zDir = 0; azDirs[0] = sqlite3_temp_directory; if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); 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( access(zDir, 07) ) continue; break; } return zDir; } /* ** Create a temporary file name in zBuf. zBuf must be allocated |
︙ | ︙ | |||
4205 4206 4207 4208 4209 4210 4211 | /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ SimulateIOError( return SQLITE_IOERR ); | | | 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 | /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ SimulateIOError( return SQLITE_IOERR ); zDir = unixTempFileDir(); if( zDir==0 ) zDir = "."; /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= (size_t)nBuf ){ return SQLITE_ERROR; |
︙ | ︙ |