diff options
author | drh <drh@noemail.net> | 2013-04-11 01:16:15 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-04-11 01:16:15 +0000 |
commit | fbc7e8845d6c3a0b140306d46c3454ca6ac45288 (patch) | |
tree | 1bbe4d602423c8bb7deaa81a0aded37d20eb6cf6 /src/os_unix.c | |
parent | 08d418904a124936ff274240795a471cc6c1af77 (diff) | |
download | sqlite-fbc7e8845d6c3a0b140306d46c3454ca6ac45288.tar.gz sqlite-fbc7e8845d6c3a0b140306d46c3454ca6ac45288.zip |
Have the UNIX VFS issue warnings via sqlite3_log() if a database file is
renamed or unlinked or linked to more than one name while the file is open.
FossilOrigin-Name: e238dcf9189c029fbdcf89339e21d9cdd8fbf2c5
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index a65f894eb..778575f7b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -280,6 +280,7 @@ struct unixFile { #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ +#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */ /* ** Include code that is common to all os_*.c files @@ -799,7 +800,6 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { } - /****************************************************************************** ****************** Begin Unique File ID Utility Used By VxWorks *************** ** @@ -1301,6 +1301,50 @@ static int findInodeInfo( /* +** Check a unixFile that is a database. Verify the following: +** +** (1) There is exactly one hard link on the file +** (2) The file is not a symbolic link +** (3) The file has not been renamed or unlinked +** +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. +*/ +static void verifyDbFile(unixFile *pFile){ + struct stat buf; + int rc; + if( pFile->ctrlFlags & UNIXFILE_WARNED ){ + /* One or more of the following warnings have already been issued. Do not + ** repeat them so as not to clutter the error log */ + return; + } + rc = osFstat(pFile->h, &buf); + if( rc!=0 ){ + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( buf.st_nlink>1 ){ + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( pFile->pInode!=0 + && ((rc = osStat(pFile->zPath, &buf))!=0 + || buf.st_ino!=pFile->pInode->fileId.ino) + ){ + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } +} + + +/* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut ** to a non-zero value otherwise *pResOut is set to zero. The return value @@ -1876,6 +1920,7 @@ static int closeUnixFile(sqlite3_file *id){ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; + verifyDbFile(pFile); unixUnlock(id, NO_LOCK); unixEnterMutex(); @@ -4539,6 +4584,7 @@ static void unixUnmapfile(unixFile *pFd){ #endif } +#ifndef SQLITE_DISABLE_MMAP /* ** Return the system page size. */ @@ -4551,6 +4597,7 @@ static int unixGetPagesize(void){ return (int)sysconf(_SC_PAGESIZE); #endif } +#endif /* SQLITE_DISABLE_MMAP */ #ifndef SQLITE_DISABLE_MMAP /* @@ -4656,10 +4703,10 @@ static void unixRemapfile( ** code otherwise. */ static int unixMapfile(unixFile *pFd, i64 nByte){ +#ifndef SQLITE_DISABLE_MMAP i64 nMap = nByte; int rc; -#ifndef SQLITE_DISABLE_MMAP assert( nMap>=0 || pFd->nFetchOut==0 ); if( pFd->nFetchOut>0 ) return SQLITE_OK; @@ -4700,7 +4747,9 @@ static int unixMapfile(unixFile *pFd, i64 nByte){ ** release the reference by calling unixUnfetch(). */ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#ifndef SQLITE_DISABLE_MMAP unixFile *pFd = (unixFile *)fd; /* The underlying database file */ +#endif *pp = 0; #ifndef SQLITE_DISABLE_MMAP @@ -5222,6 +5271,7 @@ static int fillInUnixFile( }else{ pNew->pMethod = pLockingStyle; OpenCounter(+1); + verifyDbFile(pNew); } return rc; } |