From 5968593b5119907b844fd284dc9ec403291c6554 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Sep 2006 13:47:11 +0000 Subject: [PATCH] Enhanced I/O error simulation. (CVS 3418) FossilOrigin-Name: 86931854fc5a63571719639d9a23b1d6614a6153 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/os_common.h | 8 ++++---- src/os_os2.c | 12 ++++++------ src/os_unix.c | 45 +++++++++++++++++++++++++++++++-------------- src/os_win.c | 14 +++++++------- 6 files changed, 58 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 920421fdc1..a7ab272058 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sFTS1\stables\shave\sa\snew\sautomatic\scolumn\snamed\s"offset"\sthat\sreturns\na\sstring\scontaining\sbyte\soffset\sinformation\sfor\sall\smatching\sterms.\nAlso\sadded\sa\slarge\stest\scase\sbased\son\sSQLite\smailing\slist\sentries.\s(CVS\s3417) -D 2006-09-14T01:17:31 +C Enhanced\sI/O\serror\ssimulation.\s(CVS\s3418) +D 2006-09-14T13:47:11 F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -67,14 +67,14 @@ F src/main.c f780d73b3093807bd177d21af703665b3b15a452 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235 F src/os.h 3fd6a022bafd620fdfd779a51dccb42f31c97f75 -F src/os_common.h 108cd719c96a2b714b64e02aeabbd40684274e6a -F src/os_os2.c 1cf00781716ae8f9ae1d886e819c55731249b3a8 +F src/os_common.h 31e4b5c0a3eba5867fe9cf74211da45aed542d0f +F src/os_os2.c 361964755f361b5ba879549c201284ce61ee9431 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 -F src/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7 +F src/os_unix.c 4a99fca111a7189b095d09301b950e323fede937 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e -F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f +F src/os_win.c a66763099e093785bee7e8cff3baef01868b2e73 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c e51c079b3cad8394898a6c22330150339103700a F src/pager.h 0cff9de5e9019cb695a04d18df8caaaff933a272 @@ -398,7 +398,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P afd40184b752f641b423ceffac2476f2cfbdfd31 -R ca773c981e9d66672176c6dfb66c4d51 +P f25cfa1aec0e4c1fe07176039a1b7f4e6a2c66ec +R b55f01c726f00ed378fcf34ec0beb5ca U drh -Z a0cf419bdc2fb2e2cc1249db2fd8f262 +Z 3359adac0d0ee93765223d8a4a325247 diff --git a/manifest.uuid b/manifest.uuid index fc7c30426c..fcfb3751d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f25cfa1aec0e4c1fe07176039a1b7f4e6a2c66ec \ No newline at end of file +86931854fc5a63571719639d9a23b1d6614a6153 \ No newline at end of file diff --git a/src/os_common.h b/src/os_common.h index d65c352ddf..d5818d56fd 100644 --- a/src/os_common.h +++ b/src/os_common.h @@ -92,18 +92,18 @@ int sqlite3_io_error_hit = 0; int sqlite3_io_error_pending = 0; int sqlite3_diskfull_pending = 0; int sqlite3_diskfull = 0; -#define SimulateIOError(A) \ +#define SimulateIOError(CODE) \ if( sqlite3_io_error_pending ) \ - if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; } + if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; } static void local_ioerr(){ sqlite3_io_error_hit = 1; /* Really just a place to set a breakpoint */ } -#define SimulateDiskfullError \ +#define SimulateDiskfullError(CODE) \ if( sqlite3_diskfull_pending ){ \ if( sqlite3_diskfull_pending == 1 ){ \ local_ioerr(); \ sqlite3_diskfull = 1; \ - return SQLITE_FULL; \ + CODE; \ }else{ \ sqlite3_diskfull_pending--; \ } \ diff --git a/src/os_os2.c b/src/os_os2.c index 3e5bac90f2..b29e965a5d 100644 --- a/src/os_os2.c +++ b/src/os_os2.c @@ -287,7 +287,7 @@ int os2Close( OsFile **pld ){ int os2Read( OsFile *id, void *pBuf, int amt ){ ULONG got; assert( id!=0 ); - SimulateIOError( SQLITE_IOERR ); + SimulateIOError( return SQLITE_IOERR ); TRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); DosRead( ((os2File*)id)->h, pBuf, amt, &got ); return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR; @@ -301,8 +301,8 @@ int os2Write( OsFile *id, const void *pBuf, int amt ){ APIRET rc = NO_ERROR; ULONG wrote; assert( id!=0 ); - SimulateIOError( SQLITE_IOERR ); - SimulateDiskfullError; + SimulateIOError( return SQLITE_IOERR ); + SimulateDiskfullError( return SQLITE_FULL ); TRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype ); while( amt > 0 && (rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){ @@ -339,7 +339,7 @@ int os2Sync( OsFile *id, int dataOnly ){ ** than UNIX. */ int sqlite3Os2SyncDirectory( const char *zDirname ){ - SimulateIOError( SQLITE_IOERR ); + SimulateIOError( return SQLITE_IOERR ); return SQLITE_OK; } @@ -351,7 +351,7 @@ int os2Truncate( OsFile *id, i64 nByte ){ ULONG upperBits = nByte>>32; assert( id!=0 ); TRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte ); - SimulateIOError( SQLITE_IOERR ); + SimulateIOError( return SQLITE_IOERR ); rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits ); if( rc != NO_ERROR ){ return SQLITE_IOERR; @@ -368,7 +368,7 @@ int os2FileSize( OsFile *id, i64 *pSize ){ FILESTATUS3 fsts3FileInfo; memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo)); assert( id!=0 ); - SimulateIOError( SQLITE_IOERR ); + SimulateIOError( return SQLITE_IOERR ); rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) ); if( rc == NO_ERROR ){ *pSize = fsts3FileInfo.cbFile; diff --git a/src/os_unix.c b/src/os_unix.c index 5b58cb7aac..ed810d6df2 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -928,14 +928,13 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){ static int unixRead(OsFile *id, void *pBuf, int amt){ int got; assert( id ); - SimulateIOError(SQLITE_IOERR); TIMER_START; got = seekAndRead((unixFile*)id, pBuf, amt); TIMER_END; TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got, last_page, TIMER_ELAPSED); SEEK(0); - /* if( got<0 ) got = 0; */ + SimulateIOError( got=0 ); if( got==amt ){ return SQLITE_OK; }else{ @@ -970,8 +969,6 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){ int wrote = 0; assert( id ); assert( amt>0 ); - SimulateIOError(SQLITE_IOERR); - SimulateDiskfullError; TIMER_START; while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){ amt -= wrote; @@ -981,8 +978,14 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){ TRACE5("WRITE %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote, last_page, TIMER_ELAPSED); SEEK(0); + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); if( amt>0 ){ - return SQLITE_FULL; + if( wrote<0 ){ + return SQLITE_IOERR; + }else{ + return SQLITE_FULL; + } } return SQLITE_OK; } @@ -994,7 +997,7 @@ static int unixSeek(OsFile *id, i64 offset){ assert( id ); SEEK(offset/1024 + 1); #ifdef SQLITE_TEST - if( offset ) SimulateDiskfullError + if( offset ) SimulateDiskfullError(return SQLITE_FULL); #endif ((unixFile*)id)->offset = offset; return SQLITE_OK; @@ -1096,11 +1099,13 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ ** will not roll back - possibly leading to database corruption. */ static int unixSync(OsFile *id, int dataOnly){ + int rc; unixFile *pFile = (unixFile*)id; assert( pFile ); - SimulateIOError(SQLITE_IOERR); TRACE2("SYNC %-3d\n", pFile->h); - if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){ + rc = full_fsync(pFile->h, pFile->fullSync, dataOnly); + SimulateIOError( rc=1 ); + if( rc ){ return SQLITE_IOERR; } if( pFile->dirfd>=0 ){ @@ -1141,7 +1146,6 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ #else int fd; int r; - SimulateIOError(SQLITE_IOERR); fd = open(zDirname, O_RDONLY|O_BINARY, 0); TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname); if( fd<0 ){ @@ -1149,7 +1153,12 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ } r = fsync(fd); close(fd); - return ((r==0)?SQLITE_OK:SQLITE_IOERR); + SimulateIOError( r=1 ); + if( r ){ + return SQLITE_IOERR; + }else{ + return SQLITE_OK; + } #endif } @@ -1157,19 +1166,27 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ ** Truncate an open file to a specified size */ static int unixTruncate(OsFile *id, i64 nByte){ + int rc; assert( id ); - SimulateIOError(SQLITE_IOERR); - return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; + rc = ftruncate(((unixFile*)id)->h, nByte); + SimulateIOError( rc=1 ); + if( rc ){ + return SQLITE_IOERR; + }else{ + return SQLITE_OK; + } } /* ** Determine the current size of a file in bytes */ static int unixFileSize(OsFile *id, i64 *pSize){ + int rc; struct stat buf; assert( id ); - SimulateIOError(SQLITE_IOERR); - if( fstat(((unixFile*)id)->h, &buf)!=0 ){ + rc = fstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ return SQLITE_IOERR; } *pSize = buf.st_size; diff --git a/src/os_win.c b/src/os_win.c index 6c167ab5b8..aab936e1c5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -864,7 +864,7 @@ static int winClose(OsFile **pId){ static int winRead(OsFile *id, void *pBuf, int amt){ DWORD got; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR); TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){ got = 0; @@ -884,8 +884,8 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){ int rc = 0; DWORD wrote; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); - SimulateDiskfullError; + SimulateIOError(return SQLITE_IOERR); + SimulateDiskfullError(return SQLITE_FULL); TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); assert( amt>0 ); while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0 @@ -915,7 +915,7 @@ static int winSeek(OsFile *id, i64 offset){ DWORD rc; assert( id!=0 ); #ifdef SQLITE_TEST - if( offset ) SimulateDiskfullError + if( offset ) SimulateDiskfullError(return SQLITE_FULL); #endif SEEK(offset/1024 + 1); rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN); @@ -944,7 +944,7 @@ static int winSync(OsFile *id, int dataOnly){ ** than UNIX. */ int sqlite3WinSyncDirectory(const char *zDirname){ - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR); return SQLITE_OK; } @@ -955,7 +955,7 @@ static int winTruncate(OsFile *id, i64 nByte){ LONG upperBits = nByte>>32; assert( id!=0 ); TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR); SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN); SetEndOfFile(((winFile*)id)->h); return SQLITE_OK; @@ -967,7 +967,7 @@ static int winTruncate(OsFile *id, i64 nByte){ static int winFileSize(OsFile *id, i64 *pSize){ DWORD upperBits, lowerBits; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR); lowerBits = GetFileSize(((winFile*)id)->h, &upperBits); *pSize = (((i64)upperBits)<<32) + lowerBits; return SQLITE_OK;